From bedc61c3d0346c62bb72605a5456503205a820ce Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 22 Feb 2025 01:37:02 +0200 Subject: [PATCH] feat(import/zip): support UTF-16 LE with BOM (closes #1241) --- .../IREN.Reports.Q2.FY25.Results_files.zip | Bin 0 -> 22428 bytes src/services/import/single.ts | 19 +---- src/services/import/zip.spec.ts | 65 ++++++++++-------- src/services/import/zip.ts | 4 +- src/services/utils.ts | 32 +++++++++ 5 files changed, 73 insertions(+), 47 deletions(-) create mode 100644 src/services/import/samples/IREN.Reports.Q2.FY25.Results_files.zip diff --git a/src/services/import/samples/IREN.Reports.Q2.FY25.Results_files.zip b/src/services/import/samples/IREN.Reports.Q2.FY25.Results_files.zip new file mode 100644 index 0000000000000000000000000000000000000000..86c9de9b5c89968bf36494767960305f95f39570 GIT binary patch literal 22428 zcmeFXcU)83wm<5&H?W`}B4DFeK|s1&=~a3SD7_;k^uQJsq)YE0-2kCOs6heg9TFfR zASDTqK%^ugguugn&b{aU%6;$t|4u&1$QWaNM_FUdH8aOtd8K*g?5$J3Uw&3b=6^H) zB#%zrKc%j(taD%A{;j9Cug`rwvHL1!ViG5^575om$J)W!&E7`@7;xp(A7_8t{7sAu z8BSf$n`?G_iEMWK{r&3i02fbP{67Ln|IY&0db)Xf``9|!yW6|JdHdGc!%;ZE-R-{% zi#-YXJFNWJcaJX7tLJ~xiaTDe($v_#WbvPt>amAzpWP)T#fzkRt!HLjJy9Zq7cw|8M0x{m-lB9{>IFN%Z}cRv$F@dR_kD{e`!j)UznF zZB0WIb1`@==-;{cnI(+y_8#a!tqE4*8~gnc9jpDr_vrNR(p)EF{>(cm&DP21zc0;` z|5<5#e~&J^H@NGH32Rb6RDv=+VW?F1$C3`R?mK?C@89 z7dJf~oc>Vl>%#~4JD_TbXO*&iFKO`XJuFb?xpm|5w<19gR?3sD(L7no0x_R9(&9Ke zOkH=eyl;E@)v3Quo%$*B8kp5Y-P7{=eEL+ZBQz>Jrk-bbZfb8y+$7_I;rPrz?b9j? zHUX_NB}4gekp<(iuK}l4tr(nD8*t|ue2c?PW%>jzbJEqP?}hMM_xxDq74?eD;F2IN z^as{n&Q8+%YDETcTzyzm@mx>*rVNu)_g5AZ(~=Rr2EI0+HbcnG8{b{@oDX=9xlGtb zF0-DU%w;kY4G2hRuo%wf*?+d5U?n0iC-8uOYayhpYj*kL#!iKaHS})$Jq2y$o*HI*M|l-g+9FCzlgbT8oM9v z=2@d#$HWap^6}!|6`Zr^vB_l8+WT(VCB~v@e(4;!;&d^}Z`7hxnzvZI^2=v7r)B)z zJffnRJ@Sj}XA!hOSG+!iS;y{6T+X=jcwfH-gYP6mxq$XU8~d^lSR9Gn1Ok)zRMK5^^mLlOs0kpebUs%8!T%2g>Gg^IVmxJ*NCVlnZP+>Ig$^z ziWtX|On*9VV8*b|Pm({IIXj@cf(zKt;9I-L=jw6{P^ zrkFVW)oXe7)LY9_r-q10EYwVLYohbhU>?x*&G1{K`1^0L@TliEA?$0c9PI`6S}xPj8ahPZflkPlNT3p$B)FYbxWn(KpJio}rddMtFn#{yQB5 zZ4#FfRI{FN-3hJETmfbTJuIWA;B_GTr^Bc3(ZcOi^rk z0X$gfq&Bl`T(TLi`2uKOVcwt|_AXN%+G1rZ2d$4qsTydzhdIC%{miGOx^?lD+sx+k zu)$Yaml~$j;s)nXO`q#IbaA?J&aqS-PRUYrKJFaO&y;cfmkZv3a{{rW@2otT21)jP za+-AtE3P~D6BFJQIAfj@0;t=FTQVZn3U&Aw%Fm7l`09gAhxA@aa+7ZT!=5GPvx7`h}$Jw>3ibVH4=<{SUS9ov318~LHkCAXale$af<8Fn@-Xz z&PvvWOmIbnh?r%AM@AGs*kB2uzko5ReJuT5%Vm3Po(=VNtBZQwcV3be)_&i;%2Pcg zt$2y?iM5OBOWm0}CIM1=axYh^ia_dj7S(SNXyzeX(~GjL8R8GWV{ZD^%xd=MIX|O{ zcT^5|;zYZ;SkbpdO59dwfgz@6q^+1;xbyB^%RJA{S$d)JPqq(GXqHYb=}%SJcdpoc zt*dwADM--$GFou+m!c<}24IcCRl2Ot`E6z&G04Ewd38v!NkY?HRy}fSu#u~BwmtY; z>G9EmM`fzAFi)1%`Zc-Nld@lk2Wsx3+qIvczLbJ2ZBUZK*HY& zz~dY(7sgUXxt@7nwEO7+d1}|3q%WFnd3&T$(QKk^V`)->(HtBkFIf7cAQOp z6>7xt#wwmY5_u4J`XSE-bGly8_!KjfM(I@E!wqjJ0EXDe>PxO`L0>GESYQo*cvYaS zg7ha5KW?_u?7xReE_f;&JY>?)D9=J@tGc6l)u=5bMf5?*>_yx(X)C`AP~OWqCLLPD zEM!z~i!;}BB+nfSySfJy%WqH%@5$BChB+jJhfvTibC*A=rf-DSca00wrQdFL=5{Nc z=&%!08yf$BLk}!P-U-734NufcHbcp z++t0qcqHK@DfuHE|CETS;n|N2{a==TfgsHP>Kcd9dV zL;=>tH~pzZn~NVt^lrsmjn$73_kF6~5~`Y}yc}uT*Lzdh+{NV+>FHJ6!_re)_Tme& z4{^=Wjg?o}%d9nFIXvN>TYoG)j&D$ETLC}5?dd!D+RD{&Vr}vIgB>tcidE6NM9l)z zPZRBmFHV;5jw}zauU2bCxSLAIWomcGVh*EqZCkENLwBJqkGj`bj2n(-l>~>WA2{XSdq&yXkggmC={LDmY+dr zakcS(!$DtV#Mjhhaa?!Y?$;7n3@EPKi?%y^c;kk^BBo026DRy^rx3r{X8oNK9Tp)d zLB}!lJSTNN;@(EVu<(42Mn;bL*P)aVA$w7p)Zt@^9zpXx3`)Je1z;pWxQ3jYRPqoy?F>*2Yg2J?asoZIM1?*ZgHN$ z8Sy=;TEqtwmfEK&+gKylb~}!HA~TdKgTLh$OfOs*F*!6sQZ)L5e6E_jOn~U+EOkVN zl-Mr)8hfqqhn_?@)rUo``3x}k%Pt~;?wo}Kaz-o8*EVQc+A9h!eQyqV)bpB)T;0Jt z`>x~m+^yqhs9v+a2)JH!Bl533gp`x$>F3`s?v@(19jp%P zsAx_&-#{e^e4|xFc{p?Cy3E|TwrAE*#9drDIP&7U@J+U1Nw2#h=5qHz3V$Zvq9_Ky ztsVC|LjtbHwxn~qHotvz9A~Kt>g1mg5OtKzef*Q@>qPiy*x7Gs#o2xbNBaw@ylfA2 znAf86a{83+NLw%9^5(MFxw7m4+(4ka_+MdRxgYi#9?)X@$$M?$pw8)YUoJmiia$#_7p`ygAn{pdAS{`Oc)U%_&tSnKEVHgKWk3&(Q(K<&VH>H_ z^WxRRjr35ruuSAz@!&8UMbFveu}zT~Yzdt_nKO4sl0Zo(`v>aVv^XARQ$@gctP$~g zu>5uU+$0nZZFgQ5@+44PeX_PAG(qoIk&sLjF`KN>i3{xw-ijp7X>~YG5i*2=H|KOw z`)0GEGiRzp$>aAwXs0b4Xs(ZsM#i)7Hmj5nT=LW+v_=8IO@#57;L+{_oDkq z9Y}c*hO!KSU0e)OoSuDX#)-O>8!6*k)za{0$h}Z{CSkh%Rru5|NLR&bkRVB#Oj^^j$Wt|+{vX};(jvXwrA%@<4!v+X{Lk*@8GF70g6jj8N&i4z_c8M#ot?nur{ z#-G`hwb-)Gwl-5ZGFl0o)0gu!kH*2Y!E$&tPv#jO7oI69w>14i$xp-GgM=*NM2CeC z7mLi~hu7*?PQ(9tt#|NUe_+TWdD||P=)?8oqNcQ{s`+I8hgL$~rITSH*|Eq~NvUfL zEInK-?^T3)DeJ0?g?iYw)#NXj29qI;irG=kQm(zix+>nxI4pk@^i8e=KC^Sb8q!s@sN@t?hR}&IovcU`@`dOK6PXFH}a5RThhbwOLchY>l<5~ zo1pFc3iUf-g$gfrpuV%1<|8W%bHZ!tsI7Kpu|l-?@!Xzl=rj`OqPfjR>%ogsc3#R) z_*#`4D`mm%9{H1DPLWf2nV5~1LH`mm#%z$q0(6jxtj>hTitk=?Dau3gSc@zlYC&c{ z9`NY}%_t^^_8ACFq@D~V37Q3*)Nn18l;=HGvdCqOiHlp$ja$#uZmAbx$tn`3hZZzZ zk=Xj(p}GZ2o-`xS0pbW9v4AWI%`=1L*`;*NWO*tI&r*dOF3(67|7v{`>WcYPEN~fc zkBF0$$4TBckz7@rHSKI13w2%m%;F;!;x(M`G|s2-lBW^AXDZuuG$qhrVs~9i^#RXd zPgGJsm4x#>@5WmkC{tWkl7Y~K4~ai)+`OkTK~g;L_yy3@#_UiXoa2fX@zy0|KcYbo z=EX^#ILUcUi+X^o`Nu?6mo^cx{HTTN&eOVC!N zih)I#y~>|-ldK(o>9J0I@Q0815}fjs2}x@5*e0POb_U(ENR!!f%UR@{;D@l6Nn2MK zDpuHsmU1+FNZad`pmiv(Eg}P~J{bSxfrM4P5D04B(Mpls8gMi>$+eJupxZV%5m)x3qmz*Zs5bI1Zo)9SJPBIAHUno8N9-O^XWNZLa02xi*#wm-P!xhX>n@Hvm z&vg`J`ydU5M%Mgh`DiDsdBbn^&EIU@Z+87}0Dnc^!e(=+PAS2-1YhJXsZ`$TImVD! zzJ>bhWpO#pZ{<380|t@)t?-EM4dQ2vK{_D8Vc{gpo!BvX~e1Q4JWshwA$1! zzlaWeXR#&m*@K6%I2l`ImFInF9G66PMeUltWGl-~__s{Yf80~kC}dT()f{o5uRFw# z?i~xPATnYFwC5z&_opz}Gn%Y`^^n+PJ;W=qq7CYr!IDGUJeNzF!BgWgpT?t{HMu^P zD`A-V*jkR;oqdpmyVkIh7pDdQ%h07Z+k1fV;yv_(7EVZ1SAPkt1HkdZobwt=%B?r5YehJ z&6R5MrgimiJs}dRC+<#em%W~UG+EmiXAH@A)y3@#nuluiZe~`NIt(uixVZEZ3QpLN zg+r;{I5(A*d)ApA*cWy)<*3{8!ca!Jg$GVK=W((Tiv?&&;(_L|Eu}huW*LWmwdu3MxLEZ5$v72cDzf5s#)z(XcHW$em?=pJ=8DDUUYxwh1I0h9!llkHkq0QSP+olVy zJQpc`_bg=QVSyezrM1ZPzE+DS6zR!Yb65jsFtun4b!Uwc=)*J;A3b~5GYIxd*Vus- z5U*ggo+{nh;5F=qKQt-QRJD}JkE};jRT^^Ur-h z$sygL{e$PbQ(`dK*sN8HG00FhUaxOwN=$+MO_a@ye?l>JIKhzm z0PEm;yNt|p>v#O=H-2kWPwZzny<~a;VT3G^%}%ikfBGdS-{{|_DBG1e&yzI#vU&l1 zJ!Nh~voU*w79ZuloYKC7V;^=r=VCyB7}u7T*M#Iuw}@D@oUM*Q19{IQwv&5G%ma^g zU{B~!Dm0vrtGi>3-uVdA>;06Y1gJdACv(OQVBI~tBc2(-Nup{ppgsAGXQ=(MR%^U} z$$6n|)lJa&ZzJ)+4p@GmBJSb64;8a%l(qnm-IK{Ek>mo(oqT&8YnJyEFnn(~&9>}S zyzrfoG+Te=c+Wkm5Brq4aK3_0ne4bi9={kctZDwwfL2wQ7JwAupy~6UTDlIkdNy3sS0P49e_3H1 zXq0ud@rhre*<$;d(IQyH)wD{7^F^I^y(GMv`A@4mf707Vv_oHL; z64$WX4t}WVR42V`t~L@2ZfWDF1WoMmYB1htXy~l%Y^9g9j!lr-KG@;brfQ%xjg@Ob zDJ@yYGG`}@r__fK?RJ*M1HwUibsl9h(sHCDU7^@* zxnu8vH50MqnoL%J2%6$GL$W&fT=^Sd_Yc6<3Bdk0fO-M|_0RMKufK$GFKBY^NNih$ zu)e?dq6&K==}T^(7*Ni`NYT-7aw*L$Bbc?(KJO`dtbBIJ$r__RMdux`Qjz7?&Dsi< zCyTWsW@F42x~Ce~+R~jHxzdHE{KmW?O+V`}8}Do22=gXE(62_M*ic$Ya4T68zYDv> zyjj0hVh$0gE0GbcaHRN(pk2_3Lg=MalhUrAHxtroFVm~PRNC-Fe6DK8+pG`eG|L+S}2r_(4MxfDImb{Ay8!ia}p}006PUJA5~1zbdQ}x>QIH z{8=Q+uR+{rR7ew5UpF;X1hPpGc*8*dh5iTZpJ0>h;S--5k}k7)M+g6f%1F9o=pEJlFLZDw?{TLJ z6_5J*M)g1F?AJFZNh1GuTJc{o|KR^;NI#6QPpdzb{dwKgfi`bjvXk4S;uKn|N`lx~ z$0aLO=O0f%d&773eL2C@!G0@E{bVik1<#Ue>zKef=$Z;^AY|;Ezgj13bi7=b;Fx}X z&Y-VkFB6$@W#kfz&Wn!5CxF?LT@LFEMJKg66Ws9OgxjpZW&ipB$pZ{a&|-)C)L|T* z5``Uwn1kkoG>T=cSCMgax~H2OrDqXI6W)u!=B?JuQ^&B@X)Vm}N}XVqJ@mBg;)_Sw3x-1mN+Znrv8QHNVs>Ip-MiR)e3W#j8E@jbCTb>A@}B z{#?Fy(xL=%&!Cq=b;IH`d3PplL~3I5C8a3tfCrPI6_6p#Ms-e3xgi0xTFr4#}lC2SJwW4+ZCp3F?Xh1E<)QEnDsMtw#uO(g8b zW;s;3=kM0UT3WGJDC8i=Jl!rP_HJsjDdq|Oez3QOo_njfl1P=j>yo~S3-i5 z6YQ>v;}bxM(0e;^AjfG`sM|_XUc}S~Vd6Y1U}5`Jx<6tTbz#jrrnNoT(Km4BC13$i zG}LCCPMN@@`34e4*LLzETic;3>D%v7(-^vJ(GZPeW9R5DVBtl&#Wd#qiQ>YE;?DwM z&gC}^r2|Yfi(>XkaX%*VTNRLPh0mGt4NxW3fNA6pX~a>lNfd`F>zUAsoy%to7*ePC zAFMuopo&PYcoT2rsx$^5I^!1o0F;lGJ^WS{GUuDtsW|NG~)yqntK| z>2aS$<;fS7%_^oe0)(y7yFET4jBS7>3uq^h34-oz3?vP-`o*(eg^j$v-jNjes*DVq zUJ@(gL4Ye|6BUFO1G57@preJ`X_WK4dl55XuV9fYh)5>KcUf`kNiFC&kx?OFdUUHnfa9YVO$$dGm+u z!yTgPQ@coB)feRYSEtU=_1}Vlp{qhXbOdJ6HbEk=tg<>Q*8R4VenX*%^p+(s>Vz8 zE*Hy3QaUa-Qe8e$fN!Rlzwr9r&VF_4nsGQHILuOgpABFyJ8?abSrXBzJ`3%fx5{#r zvFoUfUAL#4yY*26nqJp!h|4JPfRrs8F4Rhe9VbmV%mvWottiEUo4uBcF6)t z-^Q$adGurCK`TCQ26Niq)?Un&uzu9qR*=Qr_Wj<5RaYGwJu!52GNpesDm6P2;l|wS zWjhZ8(poJjORkLa(&zjU?n!o958xr9|4T zr9zKQ?&%zS%8|dp_PP2J_2wvCr4QrX{#B~z*)saYXdFtY2Y!o<>@F)!tnkp>*+_IG zFAlxEkS$hH-&*GEUsAupbUR%KrhLbfIzMHQX9ezia8q@6HX2(ck$DYjb;j8L^rp_4 zBVA<$DDi%Q8LpyIqy#Q6Oy?`fmF;)#&^JeSOjPTKbE#uCU>}ZBCWQq*g5~zwQ(mj< zQ@^d~Bj1;ZrmE(pPtv-R8itnZ`tkK~wAW~ZY8UxbIhvRFL`<3jefyfq!K*WDMXP4l zu_|BI>9$*Qi6ote-X$Uh^`p0=$GU}P1Oi2X;T~e8aKyAbKjZqD5Zip;6{i7xD|r)s zdNG@(AjJ+)C6K9)&)srh3TP4h9*4a*w@SIz+Q_#U9OOI;{KDki& zS_-CWwO?n$cTLQ(tLae-Tkcz$Ax<+_F4ZJ2VKtwnbk7iIf3wt!YBwJutx)lndkb6W zKSy5nFf6TcN z0BMEZh(DA!5xAA`smEK%w#4JsNZe_qB?Wzm%tTm`o@C;KT(TRgG52#V^#F%Kck#4J zTCN7$RK3jqqSo6S@6#d!&xtlJ){r|!6$xAvs@EKGWL-QIPA+T0-njC>8}v2pr~rgT z25sTqjDW23VGaKIcz~l2?#)J0{?vM2_qv)isHwlZt$Q8tn#4m=s+#tZGeRGl+K1RU z+{FuUVRM_3{d^fG~r^;*-v6t|goe!ZAU2S_>tdFDNwB z<~W61Gg(NAmvTw0N;*O`Q?0iTXP*0zA#uAUWJYV0T^ zt`4u#sIh1{vm170uo8e(8Wh%Fl=PuW;C|^>-(;c0`vXEl=km5b;gJqaf9526@yeRD zGumWiRk_NV!AjePjK%Y1Iw1}>eEd=3@1A{n|Ic^lYQ(>U6K(!emgW15|9l@NvHeRp z(S}S~{-@!mT}_XF2`BD$)qNiPhvEHEk(Pf6C)!b-k&pk1^Y5U47wX^T{d-9Kdm#ON zll}Xa`Nwqf@5$lclf%D$SpGdZ{Cjfv_sZeqe)#vo?C)vu{|`&h@*9-NBN-F0ltF&- z`rNcNm&6XwA||)mpc8T=2Hn;*DrXA@xxn6~k-AxRR`PcNV+eq_S_=;rD zug1=xPDslbGPT#wVtI|fHM**>V$FrtYEHPckG3F(lC>#ikkCNF8edR!USZi9U!x-O zK*2@epHh&>jgX1XgieQ)|{cMl3uRTrrBaU`S$d9XLkr90$xUdGARzw2?+Q$s;g1jDg@ zNtS7gM}uHmSkw?c7andwBQwy5Q4xX8)%hb{ytt+gj*N~Tru7C7C&mTjFN*`s&%4K} zsT6wUiri)Dm(@!wor^-Vn8wRSI;-*~>~Dw~t58lnc$> z%3)JTYLIb#ST`|w%y=NWc-)jg$b)APD1$BM&+2dvo(ojmy zzGF+OVCatzsY_pTAeFt-s(j8moAreWZ046mNbYQJJltoYfY64-yDR3>lO)vw;#Iu52aLeg~d{O9LsqiJnXx>jY_-2rYpP3Fql+eVwp z@SysA$dR7REiiS`5UiYy$fW8|J9hgk3_eL(?MdK>7n?j7NDqr8jhJ~2P{%X_9g^nv zEIMP~zi%?_-`boLv(5li)CObKFWDe8k;QQ)rIoz}RCt4;`t#Z<&+L~Lg|di8sm%V@ zL;Vh5w!6PVdvkYgD!GFTnTbtN2hxSFtOdJPDIRv6o^%Cw>Sik@C&_v-3pL)=$`fy( z8`2={IePW{7{b3dxhT3i1t2;BWx}S8#^a)4l)77VLBpH>lyl*u~O25Us>E;U~|@5ihyIu65~q<%ozPD zK^i<--g79;sg3N69VM|*bncZJreK^E*f2`c3YC=4DrH0FfmU;rb5#LcMqUxpp{nW?N0Ep1tK*p@hsKT znu2XNt+y477ScVcl(PF_g|40@dmIV@BKPI1Hg{s4DE1!q%3)39dOJo;7uoOPQML`$ zOR=BV_+|BBCTor24*Q|;tYSC&)aE}QjH%swrJYA(8y)JQ zIde7eAVQnhTYpEV^xP8;MNLdxWUbFwztbO;x;|!1#+B$>!Z3BM-hv){@>-B9NkH4`l-)=^ zJYK`aW2h{43(`bh!Of7o2$^C>y)vvxO)FM~m9Xh%9F~*itfh;zJm5of`V(y8j8&xz z6GFXX!678&0U)?Yax)&(Fm)!6#nYs5s?|Sz(|Oi0PmL!p%hIU5F$g51P1@fYzCNeE z&;AYqW@Pet5%0a#kc_u?{7lFOimMIQtSy+JiR~9#7EQ}lp>U>sywV(OI!l64uh>s`N&W5w4kW+(BisNZ9C)mm}S%8mOP`Kr{!+dJ7d2>noe4 zm_%^|ZMobCwQ$sFu}l{Wb}0e5afv*_T$8M7(Fm+qr^g9pe;eEn7JB4=-0L#=aiJQ< z^ip3c{$@{FA_R6+Dbk&w4bRjBtm!4jrwkPclRmM^7!|LLYNA`jtv3F!;j*WZ+-RjEtj8u7qq7*>r^W7El?+BO$Pq3^;&fiUtj>cEf`e2p6OKi zE-1!i5Z9w5e^xP4uno>9-r-+T6fbtHD@PxCtHk4E|52~OW({`WjxwI4@kimWy@doz zwK648(dE@Vc{8Oh11+IPjd4p;cURtVx|n?;s|ZyKvDs(_>yEj70;lpZPSMLB;}T;$ z=SfF7Bfje&dnJc{hDbAb#Obpjauq(yxc8xDr!IJ_ab5)7_iw*uCpEDvXLqf?z-;D> zeuN4IMy9usdpG=8>Wj%f^w5g)bbqN;X4(${zaio zst>o2V;81f$J3V}J)`OXP}E^%MANM7rvuWL?nD+#lW#A>4{rKZy+IF_IuAexXg%IW zkasaSM(BiUy@uJ-aG;xFlzbHJOA{%3`Ws5p&v8idDPicXpISNGg)<|L04g{@h`jzF$3seIHp5Ry~*=-G?D@!HeuOkulhy9Pf}KG}uU0)Mpx zfehR)skQcWgNoZi0JCFNo!UWXABH^ z7oER4lBF~M@N+%R7j)_`TK&kic^06O?gON54+^itCw)uhInz~wSRN~KTFAD8(@@Ua zFl^vq1wM6OqkHQP)cVRnR48^G=ebGCo9lGplZIzF_HJUH8g($S2iPyyv-Q}(^mBb_ zhs{=LlqWGigYT{OI zz$XCYsiOD<*l8K0-2m7+e6f9abTghym189?mFv}*s1-4&d{ZqG9$+!qm;F)xo!(f! zYgB7)VR+4tgZke6^VVMqZ=tEDBmMhXczwdTVW(h!5n<20x3cp?pJz_Fq2$My74PHu z$!F}gW_>ojp221EWT4Tv(D0UPD*8Bu8TfY(Ey+%Vz4af8E&xvBG`)I%|8PhJePwQk zG*la{3kb~*$KrL1LI_Cx6t-lc;4F73L}6vDw$7E!1)F}juYCF1>lP_x9KN5eG-meL zE-GnZw>mn&~X-UlSeLV`(TcjW(OtkBRO4l948 zn<{CR+hiOp)(BUy5N0@bvwMA5pZson%ym`#3Qr==V@ChG`Y_V%_z(IxAY)u zMzk?sWyb^-6{OOg`U79%g~R%!>#98Hvug*Bhu1&dmzsgonKPVvE2eIOJEyW9$wqB5 zTgtwHbgEbOXjB%(0L8my8s7M{?i^>Q0gQ=d^Fn1@pRazQC85(6FVy;rDd%1g2Aa_l34~a%X zU$chW>Xt1=0`ON@1)?D3}2lmbhUeOJ-|}L+e-(q3BSTmx@ig*g3tu zQ!zPVRF}kx&CAAI3w3RgMltp4u?YB`A)<<;;RZ@OkOk}^^@E7IOOk?s_ z1Y`dcKR4Gz8$TOFrMlO>SazlhN*qTSr!d0qJ0Oc6ndsSr9 z)2yO53HDb*0Mw%Cw0HTG1%!e*NTwUL|CKxGsFd2`;pS4xjhBOH(r6Vm%5n^R-ayBY zP-BvKouq^!TG~>IjEZ95>g3EaV27e=#zvnWMrecI9)1f=qTk{oGmuoT5yW=@Te_Qc zA$h!OmHmvvXbSYhHB$C0w?8-1t1BE@RMRzocDY!HnZCh7u7w0Wf5Nut3)n_;1ilz@Z^mt17Q!p#&9vac4K)DGAch|X5 zR5RsOZAVuMg8J9`wjVXRmo-2Po07XE4Q7nPJlLeC<@}L@nWbRov?NLWiO1(iC7%3& zOzxH0%RylGq)C}1*5tVy7ke-hQNpO@Abj1 zutf$Os+|*us&wT_pMY)?2n(1?&&=dAhh(sM@`wgYCyonI#%`apAo?m@<+hddeCrwX z9MDS#IF)uZ9x9^;=4@K1B9}D@<87~6*L$YlTW38=X%Qps-vEjN-wwz$$5zEc7(<&4 zb>+sN5L_yl+vejSrZQm!%D7}8ZFF{(-2m&x<|Zadol0sA*Y4$(O8pYAz2J=Ib{zW< zY^%9!8JuFQ%Y_<|o0AA+455+RhN*M93 zGq?0)pL>oa-lg7j@zlr#>AJ&~uaT(+vsvka!rI6)f_M2v-4Kt;DV7Psyam>)wzi?UcaUZAqkg}^-TV?U{NlR5s z9no-%MI35?Eu9iEdOc%fK_p4H>f=M_Oc!BJ*P|ixJlp|sK0=Twfo6?V&=WHB?9?#P zs3x#gdoQrz?DoLb%+@*{hb;y226f z%JNN!jXGW(kw%AfIxOh6Wk7KBoZa>c8o*>T6*&R#(w?cW-nx6kAcezosBKD6YH;}0 zi0gzfPNzZA=h3zjo&92xr^eXxO;;goaT7trFkU>lk>kjc2$ z`2+-4t8T|e_3PXwuD_lAV!1C<(IMJbp<9XWD7# zsa^S^b!MeedkU+ssJ3V6OELD@m25a$wb1e^?wOJNbwCmirNN|ieT$)rOgD5_+UfZI zLTsH~*IWy_aBTK4PWMHp?nY$*=Ute; z39^Vmg{=~)%vL$C%ocm%Kot3!=*gy)Co>&T+PitDLzm61*uADmcILcK%W-{EOOEHX zi2woLlbv5KImuYWt|A-jXPO%0XWA0ucV|-+`KFN%5#Iv%(1L@nLgjT82+)97q zcokTdkb(OVALyQwD4T}1+t@TR(bB4O&ys_4(I|d9vMof-ZL9aSW%oYPY;Kfaj@rsa zLz9wqQ(QY%bMM!7%;pMBvf~u{mXwob24RF%7fai7OIaMh%7I30?hSYdg?yZ(ZF7CfVoS;8YZ8lfO+HXe*6lr?g5#I=}!^ z9^jnUmj>TWIC>NDm(j+en5We-qR!Kj(zGm<8aO0#?WH1q{F1XI03jZhVSYYUx%oev;OR8UB8 zlO=^|L60SPsuvXC3_h3*_Dd!GKb_opG+X%sz;W%2nt41rmWNYXI)jEbb zP)n_~SFJ^&ikOP<%zIPMu@$9gEVWdJEVUEF^eL@1L_#$pRf#1L8CfeNUYwpeuRUiv zujk$S$36G2@9+1!zklvIzw=pv%kd~i?5$-SRE5f(tm%Bz^#hq`{$RFc{X(Nq*z|0q z2_Q{_nQnH}^mv#_~qk*I@ifLM^sk(kb9~li{xTF_!^#`H6ayVZzBpwqrh4Fuoye*x1Iz?c7-4Jz0a(S$c?7NqAuOhEqn*1;#A!@p8C4rnYsm_wpm21To3$7HQc0t6` zxZ486Tb3Pbel+(SWNMrj<+!8e9;P!qmWRX#!hXsQGd=C@HaOAzSe!!q*(0XpHf+P@ zW}J(Upo=4AXIkuUR*z|%ke%}W8{d@UZXYm?Ua|=;PP^k!{Zf~pU$puJzc7l^I8FA* z5u|oq=EkKlUQXV{;BM&ML5JDDp#_%E$r5okJs2>?a}JEbTkf2^=o=+%Dp>V*5~?o} zLtkER^D~&CzA!5|p#bc%Jyk&<3y26^Yp4d#xRM{R;)%e&s%8D5lGO{k2Z> zFbT#59J<<*OZFdwu#B@~MQ9-;g$Bc*gc-54)OuUNakseOey7a3AL2;ui1~KfBC!vn z-yBr1nZeTIcZP%jN|5mcrm^CEo+o2Jx63b8cy~AbVr#yBX2Q{sB=u`>I_$fuo2{Fb z<*X}12o#N0={?0uGv-+GN|Q1xg5CU9{N|4CKjvy?dP~VuW?x>j4@1{bG)!kwEBy`6 z48pMZKerf%@AZGxIk6;+!g9sT~M1jVlV31bly`BipenlCZLJJZ;(~A3bv`nH?uZRMMDg1^s>IB}w-G#zEpCVHNg~lMMcd=~tk^6r zR`&N!8A|N{C>xJ;;;?u4H7l@9a43lLs&rr<-T!cl?d4SU2-fQw8Wk@rAodT80wQ5= zs1>@e7J_#-;&9xjI1C=k)6S^{>3~-?7qd63wwYZ1V2*o$WGez#WY} z9X`pTR~Z=X5foM4s__(g3cBZ%wv4o`Yg-kJ*3V_>I*3Nz0v;4@h=68ZGw2jc!CA*q z;QWSv^3Hu$P*ON0HU#nz27Bh#U9N**?1ARlRsn-Q-M3d&-Nh|7=wixrdXk|R=92{= zphXd6LQh;e+dW*CJWSb0OyZ(xBP2miuWdAjWQG>zjY=bzz;vFE2T}#DgzEmPg)LVS zQXdd?Ef~gnF<5S;U($neI@{yjtp;BkZK@Q++og?*I>a3lS7)`nD2NkmLFgKfl%Tnb z7ruiu(9F?A{a+Wj(}EB^9(XUWcK#$==>OFIGAb+x7-kFzz*`H;&KpW1yrlKTyOs=G zP2#;8jnujhS86StToed$y|NSh*PX8o#X+P!jo3~3Xlh@=W-(K2RM#9;Zi#IeLKS;h zm!5x#WDkBH)63rdMU4#A)=rF9{`FD}S~pfnWy^rJKsZtex?=Ubutu>n=72iu{dbtj zgDGyyT1I(QY!?2p*#q3WlJi*Z1yq0SYoO84!%_f)&r+iPi@4JHT_3b#avdWuf=h1! zaVf146YLGY<)v2R;Pt7d!f56wL+32lit-o!)p4%~usiY>TS?83Cv@gW(G*kc zsL4!jT0$%I%{b)L3C|+iMD+srbogA^yIla4^m?B(UM%%Z_@(KwcjoTFAvt69<(V9L zCpkH!ttu~fX#Je~C^~ZVv!egQ{QRBlAtdzS_tyI;yQuuf e+23V_WR*i!$kSE+*x{a#m)&-<;a~AReEScEb4eTk literal 0 HcmV?d00001 diff --git a/src/services/import/single.ts b/src/services/import/single.ts index 85bd3d48a..b572aea7f 100644 --- a/src/services/import/single.ts +++ b/src/services/import/single.ts @@ -3,14 +3,12 @@ import type BNote from "../../becca/entities/bnote.js"; import type TaskContext from "../task_context.js"; -import chardet from "chardet"; -import stripBom from "strip-bom"; import noteService from "../../services/notes.js"; import imageService from "../../services/image.js"; import protectedSessionService from "../protected_session.js"; import markdownService from "./markdown.js"; import mimeService from "./mime.js"; -import { getNoteTitle } from "../../services/utils.js"; +import { getNoteTitle, processStringOrBuffer } from "../../services/utils.js"; import importUtils from "./utils.js"; import htmlSanitizer from "../html_sanitizer.js"; import type { File } from "./common.js"; @@ -148,21 +146,6 @@ function importMarkdown(taskContext: TaskContext, file: File, parentNote: BNote) return note; } -function processStringOrBuffer(data: string | Buffer) { - if (!Buffer.isBuffer(data)) { - return data; - } - - const detectedEncoding = chardet.detect(data); - switch (detectedEncoding) { - case "UTF-16LE": - return stripBom(data.toString("utf-16le")); - case "UTF-8": - default: - return data.toString("utf-8"); - } -} - function importHtml(taskContext: TaskContext, file: File, parentNote: BNote) { let content = processStringOrBuffer(file.buffer); diff --git a/src/services/import/zip.spec.ts b/src/services/import/zip.spec.ts index c29459f93..67f0175f3 100644 --- a/src/services/import/zip.spec.ts +++ b/src/services/import/zip.spec.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { beforeAll, describe, expect, it } from "vitest"; import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; @@ -12,35 +12,46 @@ import sql_init from "../sql_init.js"; import { initializeTranslations } from "../i18n.js"; const scriptDir = dirname(fileURLToPath(import.meta.url)); -describe("processNoteContent", () => { - it("treats single MDX as Markdown in ZIP as text note", async () => { - const mdxSample = fs.readFileSync(path.join(scriptDir, "samples", "mdx.zip")); - const taskContext = TaskContext.getInstance("import-mdx", "import", { - textImportedAsText: true - }); +async function testImport(fileName: string) { + const mdxSample = fs.readFileSync(path.join(scriptDir, "samples", fileName)); + const taskContext = TaskContext.getInstance("import-mdx", "import", { + textImportedAsText: true + }); - await new Promise((resolve, reject) => { - cls.init(async () => { - initializeTranslations(); - sql_init.initializeDb(); - await sql_init.dbReady; + return new Promise<{ importedNote: BNote; rootNote: BNote }>((resolve, reject) => { + cls.init(async () => { + const rootNote = becca.getNote("root"); + if (!rootNote) { + expect(rootNote).toBeTruthy(); + return; + } - const rootNote = becca.getNote("root"); - if (!rootNote) { - expect(rootNote).toBeTruthy(); - return; - } - - const importedNote = await zip.importZip(taskContext, mdxSample, rootNote as BNote); - try { - expect(importedNote.mime).toBe("text/mdx"); - expect(importedNote.type).toBe("text"); - expect(importedNote.title).toBe("Text Note"); - } catch (e) { - reject(e); - } - resolve(); + const importedNote = await zip.importZip(taskContext, mdxSample, rootNote as BNote); + resolve({ + importedNote, + rootNote }); }); }); +} + +describe("processNoteContent", () => { + beforeAll(async () => { + initializeTranslations(); + sql_init.initializeDb(); + await sql_init.dbReady; + }); + + it("treats single MDX as Markdown in ZIP as text note", async () => { + const { importedNote } = await testImport("mdx.zip"); + expect(importedNote.mime).toBe("text/mdx"); + expect(importedNote.type).toBe("text"); + expect(importedNote.title).toBe("Text Note"); + }); + + it("can import email from Microsoft Outlook with UTF-16 with BOM", async () => { + const { rootNote, importedNote } = await testImport("IREN.Reports.Q2.FY25.Results_files.zip"); + const htmlNote = rootNote.children.find((ch) => ch.title === "IREN Reports Q2 FY25 Results"); + expect(htmlNote?.getContent().toString().substring(0, 4)).toEqual("