From 17bacd85f981180b1bf82515dfafafcada661fd7 Mon Sep 17 00:00:00 2001 From: Ashcon Partovi Date: Wed, 5 Jul 2023 13:16:10 -0700 Subject: [PATCH] Fix detect-libc --- src/bun.js/bindings/BunDetectLibcModule.cpp | 34 +++++++++++++++++ src/bun.js/bindings/BunDetectLibcModule.h | 4 ++ src/bun.js/bindings/JSSink.cpp | 2 +- src/bun.js/bindings/JSSink.h | 2 +- src/bun.js/bindings/JSSinkLookupTable.h | 2 +- src/bun.js/bindings/ZigGlobalObject.cpp | 6 +++ src/bun.js/module_loader.zig | 2 +- src/js/out/modules/thirdparty/detect-libc.js | 29 +++++++------- .../modules/thirdparty/detect-libc.linux.js | 29 -------------- src/js/thirdparty/detect-libc.js | 36 ++++++++++-------- src/js/thirdparty/detect-libc.linux.js | 35 ----------------- test/bun.lockb | Bin 141113 -> 146552 bytes test/js/first_party/detect-libc.test.ts | 20 ++++++++++ .../first_party/{undici => }/undici.test.ts | 2 +- test/js/first_party/utf-8-validate.test.ts | 9 +++++ test/package.json | 6 +-- 16 files changed, 118 insertions(+), 100 deletions(-) create mode 100644 src/bun.js/bindings/BunDetectLibcModule.cpp create mode 100644 src/bun.js/bindings/BunDetectLibcModule.h delete mode 100644 src/js/out/modules/thirdparty/detect-libc.linux.js delete mode 100644 src/js/thirdparty/detect-libc.linux.js create mode 100644 test/js/first_party/detect-libc.test.ts rename test/js/first_party/{undici => }/undici.test.ts (98%) create mode 100644 test/js/first_party/utf-8-validate.test.ts diff --git a/src/bun.js/bindings/BunDetectLibcModule.cpp b/src/bun.js/bindings/BunDetectLibcModule.cpp new file mode 100644 index 0000000000..f7e2c1945b --- /dev/null +++ b/src/bun.js/bindings/BunDetectLibcModule.cpp @@ -0,0 +1,34 @@ +#include "root.h" + +#include "JavaScriptCore/JavaScript.h" +#include "wtf/text/WTFString.h" +#include "JavaScriptCore/ObjectConstructor.h" + +#if defined(__LINUX__) +#include +#endif + +using namespace JSC; +using namespace WTF; + +JSC::JSObject* createDetectLibcModule(JSC::JSGlobalObject* globalObject) +{ + VM& vm = globalObject->vm(); + JSC::JSObject* object = nullptr; + + { + JSC::ObjectInitializationScope initializationScope(vm); + object = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 2); + #if defined(__LINUX__) + auto version = JSC::jsString(vm, makeAtomString(gnu_get_libc_version())); + auto family = JSC::jsString(vm, makeAtomString("glibc")); + #else + auto version = JSC::jsNull(); + auto family = JSC::jsNull(); + #endif + object->putDirect(vm, JSC::Identifier::fromString(vm, "version"_s), version, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); + object->putDirect(vm, JSC::Identifier::fromString(vm, "family"_s), family, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0); + } + + return object; +} diff --git a/src/bun.js/bindings/BunDetectLibcModule.h b/src/bun.js/bindings/BunDetectLibcModule.h new file mode 100644 index 0000000000..4051e6750b --- /dev/null +++ b/src/bun.js/bindings/BunDetectLibcModule.h @@ -0,0 +1,4 @@ +#include "root.h" +#include "JavaScriptCore/JSObject.h" + +JSC::JSObject* createDetectLibcModule(JSC::JSGlobalObject* globalObject); \ No newline at end of file diff --git a/src/bun.js/bindings/JSSink.cpp b/src/bun.js/bindings/JSSink.cpp index 5f99d37927..3a69cc79af 100644 --- a/src/bun.js/bindings/JSSink.cpp +++ b/src/bun.js/bindings/JSSink.cpp @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by 'make generate-sink' at 2023-07-02T16:19:51.440Z +// Generated by 'make generate-sink' at 2023-07-05T19:37:39.554Z // To regenerate this file, run: // // make generate-sink diff --git a/src/bun.js/bindings/JSSink.h b/src/bun.js/bindings/JSSink.h index 41d7065dcf..dc68935d96 100644 --- a/src/bun.js/bindings/JSSink.h +++ b/src/bun.js/bindings/JSSink.h @@ -1,6 +1,6 @@ // AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by 'make generate-sink' at 2023-07-02T16:19:51.438Z +// Generated by 'make generate-sink' at 2023-07-05T19:37:39.553Z // #pragma once diff --git a/src/bun.js/bindings/JSSinkLookupTable.h b/src/bun.js/bindings/JSSinkLookupTable.h index e4ed816295..7ff4c3f9c4 100644 --- a/src/bun.js/bindings/JSSinkLookupTable.h +++ b/src/bun.js/bindings/JSSinkLookupTable.h @@ -1,4 +1,4 @@ -// Automatically generated from src/bun.js/bindings/JSSink.cpp using /home/cirospaciari/Repos/bun/src/bun.js/WebKit/Source/JavaScriptCore/create_hash_table. DO NOT EDIT! +// Automatically generated from src/bun.js/bindings/JSSink.cpp using /Users/ashcon/Desktop/code/bun/src/bun.js/WebKit/Source/JavaScriptCore/create_hash_table. DO NOT EDIT! diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 4bb5445e16..09b82daf72 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -114,6 +114,8 @@ #include "JSEnvironmentVariableMap.h" #include "DOMIsoSubspaces.h" +#include "BunDetectLibcModule.h" + #if ENABLE(REMOTE_INSPECTOR) #include "JavaScriptCore/RemoteInspectorServer.h" #endif @@ -1587,6 +1589,10 @@ JSC: return JSValue::encode(obj); } + if (string == "detect-libc"_s) { + return JSC::JSValue::encode(createDetectLibcModule(globalObject)); + } + if (UNLIKELY(string == "noop"_s)) { auto* obj = constructEmptyObject(globalObject); obj->putDirectCustomAccessor(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "getterSetter"_s)), JSC::CustomGetterSetter::create(vm, noop_getter, noop_setter), 0); diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index e7e4d700ee..2f3f7492bd 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -1868,7 +1868,7 @@ pub const ModuleLoader = struct { .@"node:wasi" => return jsResolvedSource(jsc_vm, jsc_vm.load_builtins_from_path, .@"node:wasi", "node/wasi.js", specifier), .@"node:zlib" => return jsResolvedSource(jsc_vm, jsc_vm.load_builtins_from_path, .@"node:zlib", "node/zlib.js", specifier), - .@"detect-libc" => return jsResolvedSource(jsc_vm, jsc_vm.load_builtins_from_path, .@"detect-libc", if (Environment.isLinux) "thirdparty/detect-libc.linux.js" else "thirdparty/detect-libc.js", specifier), + .@"detect-libc" => return jsResolvedSource(jsc_vm, jsc_vm.load_builtins_from_path, .@"detect-libc", "thirdparty/detect-libc.js", specifier), .undici => return jsResolvedSource(jsc_vm, jsc_vm.load_builtins_from_path, .undici, "thirdparty/undici.js", specifier), .ws => return jsResolvedSource(jsc_vm, jsc_vm.load_builtins_from_path, .ws, "thirdparty/ws.js", specifier), diff --git a/src/js/out/modules/thirdparty/detect-libc.js b/src/js/out/modules/thirdparty/detect-libc.js index 1c4e18a7a3..47aaefa5ee 100644 --- a/src/js/out/modules/thirdparty/detect-libc.js +++ b/src/js/out/modules/thirdparty/detect-libc.js @@ -1,28 +1,31 @@ -function family() { - return Promise.resolve(familySync()); -} -function familySync() { - return null; +function version() { + return libcVersion; } function versionAsync() { - return Promise.resolve(version()); + return Promise.resolve(libcVersion); } -function version() { - return null; +function family() { + return libcFamily; } -function isNonGlibcLinuxSync() { - return !1; +function familyAsync() { + return Promise.resolve(libcFamily); } function isNonGlibcLinux() { - return Promise.resolve(isNonGlibcLinuxSync()); + return Promise.resolve(libcFamily === "musl"); } -var GLIBC = "glibc", MUSL = "musl"; +function isNonGlibcLinuxSync() { + return libcFamily === "musl"; +} +var { + version: libcVersion, + family: libcFamily +} = globalThis[Symbol.for("Bun.lazy")]("detect-libc"), GLIBC = "glibc", MUSL = "musl"; export { versionAsync, version, isNonGlibcLinuxSync, isNonGlibcLinux, - familySync, + familyAsync, family, MUSL, GLIBC diff --git a/src/js/out/modules/thirdparty/detect-libc.linux.js b/src/js/out/modules/thirdparty/detect-libc.linux.js deleted file mode 100644 index 1c4e18a7a3..0000000000 --- a/src/js/out/modules/thirdparty/detect-libc.linux.js +++ /dev/null @@ -1,29 +0,0 @@ -function family() { - return Promise.resolve(familySync()); -} -function familySync() { - return null; -} -function versionAsync() { - return Promise.resolve(version()); -} -function version() { - return null; -} -function isNonGlibcLinuxSync() { - return !1; -} -function isNonGlibcLinux() { - return Promise.resolve(isNonGlibcLinuxSync()); -} -var GLIBC = "glibc", MUSL = "musl"; -export { - versionAsync, - version, - isNonGlibcLinuxSync, - isNonGlibcLinux, - familySync, - family, - MUSL, - GLIBC -}; diff --git a/src/js/thirdparty/detect-libc.js b/src/js/thirdparty/detect-libc.js index 514a765363..21110cc668 100644 --- a/src/js/thirdparty/detect-libc.js +++ b/src/js/thirdparty/detect-libc.js @@ -1,27 +1,33 @@ -// Hardcoded module "detect-libc" for darwin -export function family() { - return Promise.resolve(familySync()); -} +// https://www.npmjs.com/package/detect-libc -export function familySync() { - return null; -} +const { + version: libcVersion, + family: libcFamily, +} = globalThis[Symbol.for("Bun.lazy")]("detect-libc"); export const GLIBC = "glibc"; export const MUSL = "musl"; -export function versionAsync() { - return Promise.resolve(version()); -} - export function version() { - return null; + return libcVersion; } -export function isNonGlibcLinuxSync() { - return false; +export function versionAsync() { + return Promise.resolve(libcVersion); +} + +export function family() { + return libcFamily; +} + +export function familyAsync() { + return Promise.resolve(libcFamily); } export function isNonGlibcLinux() { - return Promise.resolve(isNonGlibcLinuxSync()); + return Promise.resolve(libcFamily === MUSL); +} + +export function isNonGlibcLinuxSync() { + return libcFamily === MUSL; } diff --git a/src/js/thirdparty/detect-libc.linux.js b/src/js/thirdparty/detect-libc.linux.js deleted file mode 100644 index 4c65572470..0000000000 --- a/src/js/thirdparty/detect-libc.linux.js +++ /dev/null @@ -1,35 +0,0 @@ -// Hardcoded module "detect-libc" for linux -export function family() { - return Promise.resolve(familySync()); -} - -export function familySync() { - if (process.platform === "linux") { - return GLIBC; - } else { - return null; - } -} - -export const GLIBC = "glibc"; -export const MUSL = "musl"; - -export function versionAsync() { - return Promise.resolve(version()); -} - -export function version() { - if (process.platform === "linux") { - return "2.29"; - } else { - return null; - } -} - -export function isNonGlibcLinuxSync() { - return false; -} - -export function isNonGlibcLinux() { - return Promise.resolve(isNonGlibcLinuxSync()); -} diff --git a/test/bun.lockb b/test/bun.lockb index c35182d46e378de888f05757cd18177bc512d985..e8566947c2acaa1d206eb117807c19f3edcc2b0b 100755 GIT binary patch delta 39257 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 VZ5`|t<9H#$L{VB8Q%kYo{{YF@OCkUO delta 35712 zcmeHQ2UJu?_upAr?bA0Fg_RhU?r`$Vt%C`3&J+j;KncYNR zZ~d$xj@JhIT^@GwcGWVvO-HH+JV`p2R5JNdDff4W#$Fn_tcqSoSN};-9@gr8nat>P z>6Wx~N-hA3=yaKbEODu^@x66{g><^&;H!g5pu16;@;87M11$r28PIe~|1?W~ovxBW zrz-{iLr{CrcR@)%0u535*!YzGebGiS$jf$sK-lPX&Y-Od>vXQ5L7?S8kJ~C#lee~0 z8rlYZN76@aRPi*GO6W*Y@B#KbPhZ}8291;2Hc%JPm7rvY2PpM#Evlj7mr;i7=oy>l zlh`M=$2ss+%@Mp%etK+bY+N6UPN&-c0CuB_%;cnGi%&wF?gn@V(g$@1wG6cMO;6KV zbxRs0dg4_x84qj-WazUxVJt}<<)D8SR&N4od2i z5Fgt=VJYO)u{tPC^4>{(6MRwLih)fnsrN-p#FRK_?1l=#%%J$w>SaUykKK&q~u zmy#c#(o~;5DeRq;y@XPkR3h)E|ZV$Uw_rOMEQ&Diz^>61c*z6htX~E$N6C z9fBq)-Y2ndameKcW7B*3^tNQ!f~VMcTtVsRZBVl0YfvgbsAp1qPgID=VH! zucGK{ldCa0LiGeP_@9EQ0tASUOiSN^NqrMjbVb0^m_0xx6cYoJlzBhWTdAlrzwF(&N+8bkn()p`5i;fMU*1{)(f&1x2)G z=7N%$`&53tnmk%Pzb zb++Z4t@V}KQbCKOv>&v{j?z5eww$#rI0>8tO7kQwJ;4VNqq~nDlKdhljs8(ka`zrk z>iK}a2}$uuI$hj=w78TEo$f>fWsql}UD8h*Xz4@4JP|zAbNVes-Y<=MrqjLOP}Z-T zc>@V@(U+jqf%h9J4GagRf~O!SN{cQPOtz%=Oi4)7wc+au`&pZ+x#gQG#-)K$ZLw(? zedBv4rPoG28Cyfua{;AEk%^kfr45@av>YfcV1X*%tc7CkAho-};7NZF%296yn&o=* znaMoXt{jWx8Fn7l^j3Vij~?a4Rll++610vqGfO@7SJ@^kC93T z(=$>nnDM$H?G-*PJvMznnkDTf^2wW*K&f1srEdbN(w$cMb!vHw#V0YTKQC)v%6_UU zVo|)7eHHuRDmx&O$JzT@4}m3%k47sNexlOtkW)kRK*_Q(pw!@izNtyH=vcs$`{Pqm zdMAO8R`Z*HmWCXoAxCBZ*g-yVDG3>x!EqT_*!8U>fmBk4mZm~8I8!Ke6VtGH+Cp`nvW}5 zbVIdbC79h|yBk$nL>xM@A-H%awqbhF5{$2P7|bV@$h4c}7c;)f#`+-}N|c;l=mp1@ zI(lwsQ)Zr?cXIOQcgpo_H)7i5jUVoRRvO!ydU?w9(ZT~ZBs;!sPBPJ5D*a^Cy>U!e z!Rz7k1#%D%y9+bMig@M1L`Toz1(Z?HhvN_@R+J5{d5D*s%nx>BhLgC#)lJex2*V*P#PeN@ z`ug@friMvB%${e}FiAHsC2J$khG$nX8r+NMbiw?*OQ@j(Qf>I`DxuOMq`JJQk`?87 zHBI`aMY)TQNk6_QkMS`{U)vmJPX2P>}Awx*&rz!9JOGO zTfYwud!kZ6@<;sB7|O+^Uf?LtK$S_0!6|N}s&AIyF##s24wj&nP+{B)!Vx8TUVuqo zsuXvrWs-(q6Qtr8N|>?<9GO{2ZuUEH*k8!;KE_f3SeV+8CgK7iqT516s_^4Zc8>2N ztErlW99_b}gOpi`GNnVv#QH_8I~(<$jyx~WWcUtKES#SY3^n-T?9qr)`k`fbR&A4E zJp@fiAQ>=kmA>V>84V4f-d?LQWOIjBkTf zJsTvN$)W`>Qr{xgj=Kldv%#CIZrr_gJv$_DW?k7>TOruaO&Qlhaj4|$pH+{M+T z-|fz0TuqW6&isjTs~8IX)bczJc_+$q7dMks7RP>H#fccgwjMmo&7|iZJP+iK2X}Ed zNui#~G{M-R_$W`F1>rsjgHR5!f+&9Sg7d;)H}z5qV4Aoa4Wo$Tv)x0by+|ps4lTnI za6$6)38;Vx&dfn0He%__rcMeMKrq__4_LFEKig4 z1VXAhiA6q0$wkXs#$_s#aFqZ7Y|F2S<$*mgD+R zWu8~TBt3}mxj1~Ie^!ONR5Iy}Re21^z^Xh8WM@^L zSIH#(P*taE4oya0)SIgDn93$Lp63RK8NTvHsPOZ_p@!hX;>Y5BvO`Xn2)k@(=(Fno?BcUp zrPN#=W+?T=Bc;ezBBhjgjFeI$93C~x^?iVpqIVi8MbFEq$$BB>&)qA9N(+#J@$dt- zJm~~D3LSYxmCC`P;p9J_9}>)S8-+<@Ai=QEpm`eEMjqWb%NX^&utPWErpEQ#@>k1Um;mgmlIYk;^Y;GMf2RI zVQe~gZWbnehMZ<{D>U26V$GsDFsf*!4LB-=Ip$(C{D<;rhn5b$&_YXwLU_L=_n(FH z+~#3yDtB%XW;g|D5TET9DoHScA`5X=(Yat3?_|5H6!cEog>27Y#tpECY?tPRB4RS6K^y{bzl}(Fft2w zZXG6NL8gv`w~<}oGg^nS7@mt9-cT!xQPe+d$Ya`=qdPfb?*nv|<1P4gz88~$$-Hgo4bK8eW zqY!2-l(u2mF>n-jHr&hAi1(EQIwk5P(2v4Ut{%x82AlfH$F zG_YQx^+2=MPt+#84~|-bV`^Yds(Er!S6eiiW zQtW{PF~dyUIXa9D=h4w&(pEJGD8d6wJP*-e#QOW^_a8x+` zg9x72%_P-o{h~QcpRwQ?^7C~=rK3pE>B3zOW4kuWAxq&pfupUX6osl`5;#n`x}ha6 zB1K)-;c^C?(A}!MO`K%cR@v@glc&)s5*&?HVW{Xy7uRxJ(DsxMV*&~kb;{ZCD{xdR z9M~+_uALG}h?(|AeXn*rCfX$JfiPUwpk+@VsZAEIsz!sMJ?i4_!Sz^s?h|!`_1sL_29e7NFNm>UXwT>=f#@q!*^<$`T ztoQ4P`sIbE2U0aE>yxIW@1@mCaX_6j7sC1HM zQN?J*Im#N;8637{TG2ZirP1J&DNRSGv(Y>z$t0DCQCfg+QD=)7o(JKF5Gpf`7LCur zg=@`9PMx(CfZA&bj%E?O8)=lLsCn|LYB&HcoX_qYs<-RHvwEBK9lP+n-X>{k7j*#T zxp@>EmU?nbee54y6*u7^g*SlBy2{7Vv0b@KvdOR;d5ySxa;U-3jZX5EG9%SYPI07^ z+;cBv9&c-U7NnHiWk@L{?jqGvE?d95CL4uRge*ISl#=Ta`=S=4l(MUkQtG?=LKYII zl^BJT(!aw<;aw?uS|(mA+Z8FL=4F~px{Fk8#S3`*TseWeq?x3Igcpv&GBgXENmjw| zNqOKJg2Nl>T1LIQg~tpsNg0+GdlkI5#=`Rkne=xp+-0yyUnh~rfTSk!yfl*`tB3qf zCoR-)??tLbPx-wJWLZdc0juL1eaUB!D1EbMxj?{ad|m+ix|2G_MZL4{BZsG_Ff z0{J4U2f}6U=hPN5>@zxQ3vn##VTqQn*HNku3$Cn>bZY zDwn9XPwyS&izq1~Cgh7KxwsEN9ZUh}`Yn_iNCjx91_E>uCHWv?a9Jopg2BY$dKIM( z4FRYF!vMO7+5w{g%6}iAj(z|bfQbNIL~Z!_cgiJ^)^vbq7C;wKs&zI%y_f^gMU?ot z#Nc|Fl6)ROae6hU`}LcGJ8f!CqBB z)C>3;poXrg^czsRUPY7pg%1 zl=K(0EO-}E`UBMZM+^QHP>^pz-GFH@R8Rn+{dYCch#XnrbB zl#>1`4N&DoDOpSA%V~*UP(FTmxdzbE1wxIw6$Dxsw7y*I=afVyRsJ&7^Jl}$@uF5c zz?0Yfz^)`Iy`^dr#T>L&wNeB&0Y?GQhNPfv@j~skCq|`Yb|;m8nNs-}RsJ$1{cey` z*4t|S%aqE+GIei3LT)fYEnra#{1!?LB|)Dm?5&m~N()@7$`hsh{whzD9GXGjeUoem zUdRLQfs*2XNccY}>5W$PUZx}(qsoa=a;(a~Ov%IJ>30frjRz%5CV^7M6je@?l2cWl zC^alp`E-@eP-zw@T|_B4Q{{T5d4PVBLh?KG z@(W7KpDp#`k5YLJ{xcQ)(T3G>Rr(#+EPalfOescNmKNZXE|LH@q zHD0ObwWnjU+@k6cr4GM*7^bX0cqq2M@{~*s{I65-Uvnt-cylVI(W6r`IsMJ4_|2*K z&8hg!saRPJhG0o}b1J6w@#WL;n^W%PwSQy2Za)*`^qVMY`40zzN>w~OE=i5{r_V$zB zb(}hn|1_-Bwq>5BKig*0_=jyzd?t22zU;xZYmK_S)u8drSsyLE^;XYGl}9cw=Cck> zGu`vz&#^j4JYZ22?=;1MPhDhYMR-0qyQvPm@nUl;de^93Hscqy(zR(?d*jW8-wi&W zbhP$^#!b$ydHeoHtk!#d}V3;ER@+SxJ5uoRe_i z9hRC|X`a0_iXQ-HSY~Erc-v)BeDHJ!z7bqG&Xz~N z?U&3Q3Xg1X&#m0E>9@Wb6|wxtoSKKOwr|yN`$GSZA2+#KrfY|Fan1bA+dJoE4jDRc zipln*-=ucy1CB4so*4G9%}jo4wi7?U+RUnQ?==|gISzdM8Z-0ex!^j@b>Q{anpq7# zW-Uf(o&&!H&WDGri{hKX&0c3_e*6Zwp4kq()p|1v;4{|4E%P1tGjM^t`3ATJ+^P*` zR);?ZH+X>q@A{FM8Tqo0;Fg6B++m}+Rfsn1pfHO8vWe4v+`azd6wt3!n%08+-(py^$G=em9aXTCJ@pkKxa4_e_72|yZuB;c zShkrB<4M`DZ#zZ|oRvGzhkf9N%{Old-!aN2yk_y7)6)u7+Ey=b$K=$lSB|w^(4xrJ z8&fmR?Oz`qHu-L+{%=_i`k8kGT#DFH$TqIx*QfpCnq6#IbnmQgkLFdLHgya)?8)g$ zOWmZGgSu3?!ao)HD*frk=*vaUhjwyI7<#_t<$YHs4Y78(+=|~_WE;2Z{klD_kKH%O zQmys{oxyAUH+MtM2G91$-&JH&`g{1&UtWo5Bc055?}=)~U#>l;X0fK<+^KLOF?V9w z=HG>TiqgF<`ng0Ob1d@1wW|6x4i9sdj#@Wx$jpE|%*&oH`@kw~i<~Q~uRt{icIACTA_>2QlY$3mk*G0Vf!6>$vXXAAV ze~j0qyzQYVwu~>s>vGNxN3j(=8m}w)I=rsp(h)?+5sc;$Gh4&Afa`e_qj}WK*72mH zh>*`Pn&38Y=g$x!;D&u>#*e%Xf*X7cwj49F9G-Cu5po>!58M{+eH;-2Zv1gG+s1Rj zjXr_-cf!ne@G&P4Aty2azFFS)7a2C;e*31s`=(Css=Mb&nj&kW7>;sp4&diSS zE#P{74*NbgvlBe&bJ&*)`@o&z&bhD;+^}3TJHrox8=MFG^33cU&&Y#)U%)7iRVa&jmO7OW60NnVsijzJz_}VIR1QJmfs=12_A;ndS2v;HF=IeHYB^GM{k) z_FaU1;I8oI7hxZ`RTs_d8h;FK=_S~A$;@u>WtU)IKJ3dkvu}BHKJ5Dn_JO;_rLSNg zxa6^9#5uIFXgciGJD@}$eK?`zlx?tAY1HS7a7>}xaofgc1n_zLX1VrCC{#ueCi z750I9%)PI|K5*l&n%NVc3vTo^*mup$p7Al)VBdAv2ks{xavk=8n|Sg2mW!$*+xrQ&qtn?)x_>>Je`~HUsRdWW1tXnmt^VszAD;CDqzIm`t zj#K?!m)qZS>DH;t;Ge#BpK>EN_Up(xHQ)8z&sW`YY8jREpNZptSoTHoj)16}hX-eT zzubMum`;Z`Ki|2vn|tn;Zq7X)9;;$M4#ViBtLDfHe#a+amwjJz?_RH9+U+Z< znOOHAcew4uTivH~)QtNW|JxW3aAkP&A29xR5N|)wIqEUEYIhND59l1V>;c9foWnyp zM@2ux_}@dkfph25BaHv|h_^>{j@kn5Iym>obdE}TjPbvZcmr3FJO7CB{{iv#qnTCa z2f;l8=ktUPL>W&o{0|Us;Jmr_Qw;w@4F6L)5aoiidxYVCMhBuX&k*0>Zh`aTASFAsj=Fm)BffoSSuaMhkVh^`E5h*-wJ ze-7S34?a{x>%otH<{)+uUtdUtzz08f5XptWhlwr3UkC4Q1HOSsvH?H+CkJtq_=dvS zz@k_q(T_-Dagaz8;bjZbRAdloCQcA(F1!nav=AeRm_;s;mLk9oq?H&$Btqm9X)Qt| zkTzlxk+$Lnk#?eiJxHXOL8QI7OQeHnUIe70$R-jc9uw&#+7<43SuoPb5x+ID*8BNkkGvEETYbEkqJU$>JbAL=usn zVmFZ_;amcwm*_{Nw>U_okMJr9k}NWa^c5$FqzG?nHdTxu(ofuQWNoao8&>-9sX8EfZt8Xjr{#G>j9g;zmeCpL0`Z8vljonGuD63)jw}oZP)tm zx}U!O|2N$)q5W4zI!!z6<_htBl6-rm;d?^Jv>PpGGMb8iMrQpph5v%G*37@kl0ViN znty-Ng@3GJwOwmT<Nw$RynG*n`3NpS9U!bl7B{KRqo26HB3|NsE6|Z z;C#^H>h%2EWY&M8k=L|gC0GA#*1e`-wOyyS2%Ns%oHHUnP8nj0$V_KY6!W!7=R5%B*xFrN6Sm-&vn>{-a>{qn40ov>UZl z$Db_lslR+$)^6I;A2K>gYi(fR)fLEa{`;jORjA$B#T{RSXluZ4kx|*cv3*mL67cg` zl%-=j$+WvTc>5J}MwVG|Ylr_5{(~~B=9*va;osXC>#w`!?`>FZ*ZS|ezX;YJIWqqx z_uE*1OT!ew+6{lY)m5e#O{c#=X4U=075>ipaD$V-$dcdLu-dLwy^oUS1#-1^zoVCr zW`CFLXXn4atC80jg82W97TZ9N)^2)vxxzmuL;HVig}<{t>r3zLv>QgfY~9~2lh1#D zcOx{!ztVfDouTPTGwGMJ>3_(q z@+TYQ{{Nx)H|gR0_wO{UwoCqhIr{(U&RFS#rGL-;2dw|)e%b;5Xb}GXX$=3r?EZhQ zVYOYW>i&PcVYOZBztynXuJs>v|9`&~Q_p|DBs@z@iU-N?XmmdiHBky_(-t@}nzrQ@He|u1umv3(QtL_)Ef%rClE$(gd25)@u zCI;Tbz?&F&69aEz;7ttt|BnF|`_#V5FFhCb6NQJd`t(`A^PiLpN%^iAq@evAl1^Afra90dMpO?2FrX&|miG!5nnatvo1?8l8;HtbIe2u1~=V8#*5tJIH9uHP!(Vksc(osUsv_<@D42W8^w ztjbCuO^=_Ts|zUASDNfUj09OpHwvMAN8mI-S9b`g*W`iENq{R()uY=m)Vl@8LdlI?;?@|I6^`07b1$rS(meUPKDBBI_ zg9KSgc_hP+D0CD9WF_5*gk0TNONNYM+p3y|e> zgA$Te0KNmL%qR$`gB5|R09pRNDyxKaJV2LrGZK6|uL~yuuCZ!;Rp>Tq4HTK~1GO-| zC8s+G%GY>R5nq14xEIrhs_b|_BybfSEav=&RS@CBn2l(Z$-1Ba0lp~8ifHnKmzQ6A|hY}D`%zKaNGs%0pA1nfggYez(e2> z@EG_Jcmg~Ho&oe9j-LQ>6$A7@A;1PO0Cb0xS->1%9*_+z1Qr2{fhE9FnkCDTSOKg8 zRs(B*b-;Rnrqf5jMqm@L8Q2130px1(EDb{%kPgtS8U)ZxqJX4WYYfo+dG?~Op8)%S zPl5fw0eX7DK_m_VM}VWiXCh!EGg>f&IvOz=A#b2MP!qrx@N{Qg9p38FjTm(SKrJ8; zs14Ksf&e2B4A8%~@GT?VLX+;3NcXOjZ?-`b#YG$)$!b_np?k-GlfY5nG_Vz*s5=9k z1r7idG!!H>=O}WA0Pg@J0gCPvfR@#!04n>wxvZ2H+!LBd`fr1S|&T z0@HyR0Il7$R!0I;foZ@bfCI5~=b|_yVt~#7t)qTGEg%43Kp~(C;0Cw@*HGyYU??yM z=mSIpF+gXa3lITB0!@JCz!qRDunouomI6zFd1zmk4a^6!fSJH7pc5ME0CWVRfa!n$ zrT_^5t?k_bf1o_j6=hliEdVpH1K18M1C|4GfEmzh1G)lO1<;OXrMuJ=1!!9v2Mhpc z{XPtZFM;zwF~AWzS0KL*90a_8p@0<_0rUb$M(c7jpcN1Skn91<({fD9?{~meV6u`| zLB6|GKUI;G30(mjzyR2alK)|?>)N3VWnBlo0cg~MbZej+&>d(7tOSB-F~D^xQ(jH2 z)C5fwa$Y>p4WMRd)M@l-qBsNPfFb~eoIR)=@C51m0Qut!AP+bPi~!&kc`L~TrNJBq z32vBs+dD zG(fVlKsmq@Z~>fE>H%6Fa0grgH=r_5iCj|ws0eriet<9F50E9)>$*S)5De4-j6e`T zUZ4(=hZ+KJ0pWlNs1Jkz4S>b~8kiyG~Ez~@c|FR*i zGLn;CYoL`1PtbNiTY#3b_5iH_L_5;>(-P4I=nTXFT>%Q(cpw&t0}_BlzykCDdICwn z03aPm1NsA%fK;F_kPP$zQhe22K~p%m;j6e#sVV&?fOY<9Lq|JHe+$5=`xnp^rk?f z#;B3ifYtz2D1a#d2PTVkC`jQY_j5AnG=Tat6<8&5$Fe9Zb)RZj3# zQGhyj7Wf><1+D_;f$xEP0GWRmxCLATDE|s@0icdt1il9HflB}d3z0V;e0xT(@Rpx*)2fZM@(mgK;<8! zeO+N>+5)s>Ys&1U0$QcCSpEck>I^OM6nzq?15gy8s}$%MP~wXLC4f=ji-VQ~9D&k6 zMaas4TFc_a3804G0_d<(AE*c5q$8hrXj`X4jt@{1r~w26bm*b&olZ#P{tBS9_0y>- z5TK&~Z9L_W=LzZo(2na4xB@OTxyT|qACOgA15^nW&>E&wm6k`1YYkUMx)MMQQ$tj7 zMSwa>Co`=vI;qiie-Ule0j&*C-98LU3R$G}oGPGm9`(2ZD0$)KPLQ?X0O^x;bgUyw zs0`_A`NTU3X#(>o*$&CJKpUVn5Ftj4$GZsH=$isffW|;0;J38c1$w{M;>YMUoo?cQ zSfKka(tW`v1AQ1ak={tq$s-Bq3G@IG0Sk}{&{blDl4!q0?3uu-)FBz>Wv2EdD?8@z zYxMP3r1Fnl@AZn9?D_uXU3ymAH=qt>xr(+EnR6XlcZ;H^OPR_gM^ubFqGtiYzW%Mz0aXg%eNM}YJ#}PS&d4wpim47 zw?VPkXJ&;2**{;N_gt>Y=o^UTL@&loXHIU~(@!7F+1Yqpqi+-Ct_7fXc%LhFK|>#+ z7kSfJEq$b36q~`Eg0%k>rA$9oeE8^=0wpj|wNXNQr0e3R8}^^-_u(+PF1g>M^`Z;P zx@ixA4WHNNp!1_XKgb%j$Pr8QV&V)|%T0UEZrG#L8e0qB8VwD9U(}DSLN6{*``VLd zL&whlvXA^h#`vEE};iQk<$+$*%tHHgCX?WguIKVnW;J3N za@ipAtW-#J&qDj!^L>k*e0uMr$5YorqYi2}V#O#VR-=v}?Fqq4EVm{#%KZ_4g2m{d z2Y5q-_Q~t7?E6z{Uwim(#@&sde-XBQILi7{-;KJpHo|`oR4yr7d&XXzp3PdiX^*JX9=4}v)zNFZ z&J`8)=AiD&MMcLs(9AEcxHfi=*S@CHoheLfW0+v%H^s$HXu4@nHSS%1%IJQlzT6Lu zI!dS^Oz+LX@Ej|tOya=F@k4gco`=b>2NGKPz9=ce=c10=Dxc%D@5|%IpMS0PIG~p9 zX-Sbj7q;~%HEkJla{T3tE5Z7e5~t@fPknK{XgMDp@9QW^%mW?oC@z7zY0o^qUwzw_ zL}{}Z7DQi6>L47X97Q+M{K8SVEdcFbM)+ofJ}M(tQc3M8$eTNboSCv+_oSetR=4(i zWc$y8zUa`c_{RkrS}(LZwcfqwB-&70S`G7@u>HXiGjocZn-FmCLO~6CoWxr6CP;hM zvT@Usj-@Jnk8f<@{)Jk!YuK`huK0PU1OPqP6;Ky-?e5`}LZ%8npiYc5iAW ze_^p+ZBy^=D(1iwLG-~Lg@UP@e*5X$b{7jm@z-+@_&3RmOI?NI6a+^VH_?n}9XBy_ z3QKgO$3WBSv!K_&0U6IbyUXE(LHF0$mKV>bpk#^i!f7f>H1ZI;)-xxOFqOIJ{XIqI zRAgp&iY&?u@DiU9U(ZWipUM*TUsn)qrlHH)Gn%X2y>L6N+?^a$j}?RFg!UBYMbqZo zG$#{H;jqV5Iaw!oGt6K7FxIx8hrqONVOH`bV=E zN06h{gy%x^>qt>icOh)PSWWa@h^6&LHL;!e`_;r9%70c(_%8*o%tO&}5p!XZ=(h+v zc3JVkBG$ORhqtm5YrlJUtKza|SnoP_WFKHT#)%jjG%Q!|n7@kf?vSL%fhSPTX(JpK zW4G7-d9-KnrEP~>J{wS=&_gtU0?sC#iHsE1H6Rnj1S&NL)!L(4Tl4<8EAwu@)X{$yE!!Zzg4@nU4~#F1A@J7g5(?DrNmmoO*Slh7yujee8% z_ODX2M@ESkmAi|#m%!^a#H6jPbYY`>hT7r&^68kA@fM9Exvv6FB*i!wcs@o~* z$|g{j1&XOlS(4)0>dZsbSjO(sh?HNBkx)GDI^9>9CpFG2=zpU3dfEjYCX3!spdXRSRSvT+S{~7%1*SfsGSIRzhzc^h!bR z+O+h0*CA!iFPh`)Ta_@HR75HF}JagoAWv+Ne`Vk_4;(nJf zuK}md0%cCPYR~sB^tSW&r;D$wFUN;`T(F9xq%KEeD>hcNMo=oGtgx)6T+~L1=i6X*?m9Ruy(98!H5d!JqFec?J3&5+MhoY*R_hP+?0GKs3DS3 zl+_m5>(EA1v5iO@ab_JG;i^9JJJX@;qnJD6E@|GVjSqK3zxB}jQZ(4WoZYl1f;Y~1 zD{I^C#<;->0zHJ*P-U^M<*Gd!+}-V&b<*-{2W1V!Ili$F4yZy~)s-4=u=1kDM+lb( z*lB2;@MBzbI~;o-#cvsS@#68|y)zbFtv3Iho(-o{ zG`cLS1}Y^2S+MAx1GAfnVH;8ER10O9J6^}Jee{?23p>(*NS>+rV%f}h7FBS%9E136#CSo$nn={PcHYE zt-n;e)JNB#2EX9lUy%0b@(8~@^PLavbwm!{>Cm9#AnLmf8>RM8^SFMM>W3F89!yQ3 zQVe>fc4Fu@oDH?dn?H7_u(3?|JZwCR+li&ym}ijs{O`>7THE!l_wI}s`J_ZeUp!B{ z=Akn;R~;|im~!yO0a;BV#dFlEkB$^h+p+OkB1OyXSdIroid`Q=K0H!9-HnsOk?mOB z$3%+jq%<{Bl-Q5Vd66P$2l#c7B4RI;eD^?Ud!(4N1DS^+#b(Mp9VsU60*~YT@I6o} zzmvJRU5Zq8q?to&8m{bpm@ju#ejj}^QncTR4*VD?=I?|%@Ooc^n;^*&}J|4T^y7e#lWe`@DN_%2pk>$%#=Ouf>2E!^fvG}+B+1^xPL)*kBq z&i%6?))lFps9*9Ma^2Bru^MH6*#)gF@=}EAjauaQ^?PvqQG4aq5r)z1J-EiSHKBby zPpTG^5pz*-a+aovk2W6f$0q~-9S-*R#FBPjR%7=!5z!g4W}6kfS8 z$_nzv=vY`zV|V=SlV95%Wes_Eqz^(u_o3ET?t-$OS)`D{D|bOzLEZ%&ZRPYhv4fOf zxfRL^@>b}~_K6~&Vxqrt%air6<%NIxYg?YIA#Zt(;{8vV2aV3sPk+bgG!x_Yvvxlp zqE@VuupUIG;_YR8+G;nvSwa^H1=^=l$ zllEFx*cSm_Vc#jvkqLITZQQm>yLGL z-67_Idup8kaj`@wTTgUIrHM71BNnyUs%U3d5%z~!l}h318L5^uzXVHyrEhw8YX79P zj>!;o=ORPP?%I9p$V?l*jK+e7M zY!JiE(AW*;B|g5yii+tMQ8X~0mCV_9kv%aKO}6y!Vev^z?{A4s7Q3#nMPlk%7A|&$ z>I;iLS6N9>>k;$JnSGTFGvLtB_5|}3p*L9-y??Oicba+RjJ(N46c)xu%r&RcQTAcs zoC~K}4$C=nmhC8%Q|LaMj{})l{D{qesmi$OdN0xZF^gt(M1#+mSI#GoS$7X=EzwZA4nDX}F diff --git a/test/js/first_party/detect-libc.test.ts b/test/js/first_party/detect-libc.test.ts new file mode 100644 index 0000000000..a5b77994fe --- /dev/null +++ b/test/js/first_party/detect-libc.test.ts @@ -0,0 +1,20 @@ +import { test, expect } from "bun:test"; +// @ts-ignore: @types/detect-libc is not accurate +import { GLIBC, MUSL, version, versionAsync, family, familyAsync, isNonGlibcLinux, isNonGlibcLinuxSync } from "detect-libc"; + +test("detect-libc", () => { + expect(GLIBC).toBe("glibc"); + expect(MUSL).toBe("musl"); + if (process.platform === "linux") { + expect(version()).toMatch(/^\d+\.\d+/); + expect(family()).toBe(GLIBC); + expect(isNonGlibcLinuxSync()).toBeFalse(); + } else { + expect(version()).toBeNull(); + expect(family()).toBeNull(); + expect(isNonGlibcLinuxSync()).toBeFalse(); + } + expect(versionAsync()).resolves.toBe(version()); + expect(familyAsync()).resolves.toBe(family()); + expect(isNonGlibcLinux()).resolves.toBe(isNonGlibcLinuxSync()); +}); diff --git a/test/js/first_party/undici/undici.test.ts b/test/js/first_party/undici.test.ts similarity index 98% rename from test/js/first_party/undici/undici.test.ts rename to test/js/first_party/undici.test.ts index ab8430ee9f..e57ef63ba8 100644 --- a/test/js/first_party/undici/undici.test.ts +++ b/test/js/first_party/undici.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeAll, afterAll } from "bun:test"; import { request } from "undici"; -import { createServer } from "../../../http-test-server"; +import { createServer } from "../../http-test-server"; describe("undici", () => { let serverCtl: ReturnType; diff --git a/test/js/first_party/utf-8-validate.test.ts b/test/js/first_party/utf-8-validate.test.ts new file mode 100644 index 0000000000..33469c970d --- /dev/null +++ b/test/js/first_party/utf-8-validate.test.ts @@ -0,0 +1,9 @@ +import { test, expect } from "bun:test"; +import { isUtf8 } from "node:buffer"; +import isValidUTF8 from "utf-8-validate"; + +test("utf-8-validate", () => { + expect(isValidUTF8).toBe(isUtf8); + expect(isValidUTF8(Buffer.from("😀"))).toBeTrue(); + expect(isValidUTF8(Buffer.from([0xff]))).toBeFalse(); +}); diff --git a/test/package.json b/test/package.json index 5529d3f20c..da3974994b 100644 --- a/test/package.json +++ b/test/package.json @@ -1,13 +1,13 @@ { "name": "test", "devDependencies": { - "@types/dedent": "0.7.0" + "@types/dedent": "0.7.0", + "@types/react": "18.0.28", + "@types/react-dom": "18.0.11" }, "dependencies": { "@prisma/client": "4.15.0", "@swc/core": "1.3.38", - "@types/react": "18.0.28", - "@types/react-dom": "18.0.11", "bktree-fast": "0.0.7", "body-parser": "1.20.2", "dedent": "0.7.0",