@@ -2978,6 +2978,48 @@ static void Mkdtemp(const FunctionCallbackInfo<Value>& args) {
29782978 }
29792979}
29802980
2981+ static void GetFormatOfExtensionlessFile (const FunctionCallbackInfo<Value>& args) {
2982+ CHECK_EQ (args.Length (), 1 );
2983+ CHECK (args[0 ]->IsString ());
2984+
2985+ Environment* env = Environment::GetCurrent (args);
2986+ node::Utf8Value input (args.GetIsolate (), args[0 ]);
2987+
2988+ THROW_IF_INSUFFICIENT_PERMISSIONS (
2989+ env, permission::PermissionScope::kFileSystemRead , input.ToStringView ());
2990+
2991+ uv_fs_t req;
2992+ FS_SYNC_TRACE_BEGIN (open)
2993+ uv_file file = uv_fs_open (nullptr , &req, input.out (), O_RDONLY, 0 , nullptr );
2994+ FS_SYNC_TRACE_END (open);
2995+
2996+ if (req.result < 0 ) {
2997+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_JAVASCRIPT);
2998+ }
2999+
3000+ auto cleanup = OnScopeLeave ([&req, &file]() {
3001+ FS_SYNC_TRACE_BEGIN (close);
3002+ CHECK_EQ (0 , uv_fs_close (nullptr , &req, file, nullptr ));
3003+ FS_SYNC_TRACE_END (close);
3004+ uv_fs_req_cleanup (&req);
3005+ });
3006+
3007+ char buffer[4 ];
3008+ uv_buf_t buf = uv_buf_init (buffer, sizeof (buffer));
3009+ int err = uv_fs_read (nullptr , &req, file, &buf, 1 , 0 , nullptr );
3010+
3011+ if (err < 0 ) {
3012+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_JAVASCRIPT);
3013+ }
3014+
3015+ // We do this by taking advantage of the fact that all Wasm files start with the header `0x00 0x61 0x73 0x6d`
3016+ if (buffer[0 ] == 0x00 && buffer[1 ] == 0x61 && buffer[2 ] == 0x73 && buffer[3 ] == 0x6d ) {
3017+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_WASM);
3018+ }
3019+
3020+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_JAVASCRIPT);
3021+ }
3022+
29813023static bool FileURLToPath (
29823024 Environment* env,
29833025 const ada::url_aggregator& file_url,
@@ -3390,6 +3432,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
33903432 Local<ObjectTemplate> target) {
33913433 Isolate* isolate = isolate_data->isolate ();
33923434
3435+ SetMethod (isolate, target, " getFormatOfExtensionlessFile" , GetFormatOfExtensionlessFile);
33933436 SetMethod (isolate, target, " access" , Access);
33943437 SetMethod (isolate, target, " accessSync" , AccessSync);
33953438 SetMethod (isolate, target, " close" , Close);
@@ -3518,6 +3561,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
35183561 StatWatcher::RegisterExternalReferences (registry);
35193562 BindingData::RegisterExternalReferences (registry);
35203563
3564+ registry->Register (GetFormatOfExtensionlessFile);
35213565 registry->Register (Close);
35223566 registry->Register (CloseSync);
35233567 registry->Register (ExistsSync);
0 commit comments