◐ Shell
clean mode source ↗

src: implement IsInsideNodeModules() in C++ · nodejs/node@ececd22

@@ -254,6 +254,54 @@ static void ParseEnv(const FunctionCallbackInfo<Value>& args) {

254254

args.GetReturnValue().Set(dotenv.ToObject(env));

255255

}

256256257+

bool starts_with(std::string_view view, std::string_view prefix) {

258+

return view.size() >= prefix.size() &&

259+

view.substr(0, prefix.size()) == prefix;

260+

}

261+262+

static void IsInsideNodeModules(const FunctionCallbackInfo<Value>& args) {

263+

Isolate* isolate = args.GetIsolate();

264+

CHECK_EQ(args.Length(), 2);

265+

CHECK(args[0]->IsInt32()); // frame_limit

266+

// The second argument is the default value.

267+268+

int frames_limit = args[0].As<v8::Int32>()->Value();

269+

Local<StackTrace> stack =

270+

StackTrace::CurrentStackTrace(isolate, frames_limit);

271+

int frame_count = stack->GetFrameCount();

272+273+

// If the search requires looking into more than |frames_limit| frames, give

274+

// up and return the specified default value.

275+

if (frame_count == frames_limit) {

276+

return args.GetReturnValue().Set(args[1]);

277+

}

278+279+

bool result = false;

280+

for (int i = 0; i < frame_count; ++i) {

281+

Local<StackFrame> stack_frame = stack->GetFrame(isolate, i);

282+

Local<String> script_name = stack_frame->GetScriptName();

283+284+

if (script_name.IsEmpty() || script_name->Length() == 0) {

285+

continue;

286+

}

287+

Utf8Value script_name_utf8(isolate, script_name);

288+

std::string_view script_name_str = script_name_utf8.ToStringView();

289+

if (starts_with(script_name_str,

290+

"node:")) { // Ported to work with C++17 on 20.x.

291+

continue;

292+

}

293+

if (script_name_str.find("/node_modules/") != std::string::npos ||

294+

script_name_str.find("\\node_modules\\") != std::string::npos ||

295+

script_name_str.find("/node_modules\\") != std::string::npos ||

296+

script_name_str.find("\\node_modules/") != std::string::npos) {

297+

result = true;

298+

break;

299+

}

300+

}

301+302+

args.GetReturnValue().Set(result);

303+

}

304+257305

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {

258306

registry->Register(GetPromiseDetails);

259307

registry->Register(GetProxyDetails);

@@ -269,6 +317,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {

269317

registry->Register(FastGuessHandleType);

270318

registry->Register(fast_guess_handle_type_.GetTypeInfo());

271319

registry->Register(ParseEnv);

320+

registry->Register(IsInsideNodeModules);

272321

}

273322274323

void Initialize(Local<Object> target,

@@ -338,6 +387,7 @@ void Initialize(Local<Object> target,

338387

target->Set(context, env->constants_string(), constants).Check();

339388

}

340389390+

SetMethod(context, target, "isInsideNodeModules", IsInsideNodeModules);

341391

SetMethodNoSideEffect(

342392

context, target, "getPromiseDetails", GetPromiseDetails);

343393

SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails);