diff options
Diffstat (limited to 'src/bun.js/bindings/ModuleLoader.cpp')
-rw-r--r-- | src/bun.js/bindings/ModuleLoader.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp index 4e2de9294..252c446b1 100644 --- a/src/bun.js/bindings/ModuleLoader.cpp +++ b/src/bun.js/bindings/ModuleLoader.cpp @@ -516,6 +516,29 @@ JSValue fetchCommonJSModule( RELEASE_AND_RETURN(scope, {}); } + // The JSONForObjectLoader tag is source code returned from Bun that needs + // to go through the JSON parser in JSC. + // + // We don't use JSON.parse directly in JS because we want the top-level keys of the JSON + // object to be accessible as named imports. + // + // We don't use Bun's JSON parser because JSON.parse is faster and + // handles stack overflow better. + // + // When parsing tsconfig.*.json or jsconfig.*.json, we go through Bun's JSON + // parser instead to support comments and trailing commas. + if (res->result.value.tag == SyntheticModuleType::JSONForObjectLoader) { + JSC::JSValue value = JSC::JSONParse(globalObject, Bun::toWTFString(res->result.value.source_code)); + if (!value) { + JSC::throwException(globalObject, scope, JSC::createSyntaxError(globalObject, "Failed to parse JSON"_s)); + RELEASE_AND_RETURN(scope, {}); + } + + target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, value.isCell() && value.isCallable() ? JSC::PropertyAttribute::Function | 0 : 0); + target->hasEvaluated = true; + RELEASE_AND_RETURN(scope, target); + } + auto&& provider = Zig::SourceProvider::create(globalObject, res->result.value); globalObject->moduleLoader()->provideFetch(globalObject, specifierValue, JSC::SourceCode(provider)); RETURN_IF_EXCEPTION(scope, {}); @@ -647,6 +670,34 @@ static JSValue fetchESMSourceCode( return reject(exception); } + // The JSONForObjectLoader tag is source code returned from Bun that needs + // to go through the JSON parser in JSC. + // + // We don't use JSON.parse directly in JS because we want the top-level keys of the JSON + // object to be accessible as named imports. + // + // We don't use Bun's JSON parser because JSON.parse is faster and + // handles stack overflow better. + // + // When parsing tsconfig.*.json or jsconfig.*.json, we go through Bun's JSON + // parser instead to support comments and trailing commas. + if (res->result.value.tag == SyntheticModuleType::JSONForObjectLoader) { + JSC::JSValue value = JSC::JSONParse(globalObject, Bun::toWTFString(res->result.value.source_code)); + if (!value) { + return reject(JSC::JSValue(JSC::createSyntaxError(globalObject, "Failed to parse JSON"_s))); + } + + // JSON can become strings, null, numbers, booleans so we must handle "export default 123" + auto function = generateJSValueModuleSourceCode( + globalObject, + value); + auto source = JSC::SourceCode( + JSC::SyntheticSourceProvider::create(WTFMove(function), + JSC::SourceOrigin(), Bun::toWTFString(*specifier))); + JSC::ensureStillAliveHere(value); + return rejectOrResolve(JSSourceCode::create(globalObject->vm(), WTFMove(source))); + } + auto&& provider = Zig::SourceProvider::create(globalObject, res->result.value); return rejectOrResolve(JSC::JSSourceCode::create(vm, JSC::SourceCode(provider))); } |