// Copyright (c) 2017-2022 Cloudflare, Inc. // Licensed under the Apache 2.0 license found in the LICENSE file or at: // https://opensource.org/licenses/Apache-2.0 #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace workerd::api { // An object with a [Symbol.dispose]() method to remove patch to environment. Not exposed // publically, just used to implement Python's `patch_env()` context manager. // See src/pyodide/internal/envHelpers.ts class PythonPatchedEnv: public jsg::Object { public: PythonPatchedEnv(jsg::Lock& js, jsg::AsyncContextFrame::StorageKey& key, jsg::Value store) { scope.emplace(js, key, kj::mv(store)); } void dispose() { scope = kj::none; } JSG_RESOURCE_TYPE(PythonPatchedEnv) { JSG_DISPOSE(dispose); } private: kj::Maybe scope; }; class EnvModule final: public jsg::Object { public: EnvModule() = default; EnvModule(jsg::Lock&, const jsg::Url&) {} kj::Maybe getCurrentEnv(jsg::Lock& js); kj::Maybe getCurrentExports(jsg::Lock& js); // Arranges to propagate the given newEnv in the async context. jsg::JsRef withEnv( jsg::Lock& js, jsg::Value newEnv, jsg::Function()> fn); jsg::JsRef withExports( jsg::Lock& js, jsg::Value newExports, jsg::Function()> fn); jsg::JsRef withEnvAndExports(jsg::Lock& js, jsg::Value newEnv, jsg::Value newExports, jsg::Function()> fn); // Patch environment and return an object with a [Symbol.dispose]() method to restore it. // Not exposed publically, just used to implement Python's `patch_env()` context manager. // See src/pyodide/internal/envHelpers.ts jsg::Ref pythonPatchEnv(jsg::Lock& js, jsg::Value newEnv); JSG_RESOURCE_TYPE(EnvModule) { JSG_METHOD(getCurrentEnv); JSG_METHOD(getCurrentExports); JSG_METHOD(withEnv); JSG_METHOD(withExports); JSG_METHOD(withEnvAndExports); JSG_METHOD(pythonPatchEnv); } }; template void registerModules(Registry& registry, auto featureFlags) { node::registerNodeJsCompatModules(registry, featureFlags); registerUnsafeModules(registry, featureFlags); if (featureFlags.getRttiApi()) { registerRTTIModule(registry); } if (featureFlags.getUnsafeModule()) { registerUnsafeModule(registry); } registerSocketsModule(registry, featureFlags); registerBase64Module(registry, featureFlags); registerMessageChannelModule(registry, featureFlags); registry.addBuiltinBundle(CLOUDFLARE_BUNDLE); registerWorkersModule(registry, featureFlags); registerTracingModule(registry, featureFlags); registry.template addBuiltinModule( "cloudflare-internal:env", workerd::jsg::ModuleRegistry::Type::INTERNAL); registry.template addBuiltinModule( "cloudflare-internal:filesystem", workerd::jsg::ModuleRegistry::Type::INTERNAL); } template void registerBuiltinModules(jsg::modules::ModuleRegistry::Builder& builder, auto featureFlags) { builder.add(node::getInternalNodeJsCompatModuleBundle(featureFlags)); builder.add(node::getExternalNodeJsCompatModuleBundle(featureFlags)); builder.add(getInternalSocketModuleBundle(featureFlags)); builder.add(getInternalBase64ModuleBundle(featureFlags)); builder.add(getInternalMessageChannelModuleBundle(featureFlags)); builder.add(getInternalRpcModuleBundle(featureFlags)); builder.add(getInternalUnsafeModuleBundle(featureFlags)); builder.add(getInternalTracingModuleBundle(featureFlags)); if (featureFlags.getUnsafeModule()) { builder.add(getExternalUnsafeModuleBundle(featureFlags)); } if (featureFlags.getRttiApi()) { builder.add(getExternalRttiModuleBundle(featureFlags)); } { jsg::modules::ModuleBundle::BuiltinBuilder builtinsBuilder( jsg::modules::ModuleBundle::BuiltinBuilder::Type::BUILTIN); jsg::modules::ModuleBundle::getBuiltInBundleFromCapnp(builtinsBuilder, CLOUDFLARE_BUNDLE); builder.add(builtinsBuilder.finish()); } { jsg::modules::ModuleBundle::BuiltinBuilder builtinsBuilder( jsg::modules::ModuleBundle::BuiltinBuilder::Type::BUILTIN_ONLY); builtinsBuilder.addObject("cloudflare-internal:env"_url); builtinsBuilder.addObject("cloudflare-internal:filesystem"_url); jsg::modules::ModuleBundle::getBuiltInBundleFromCapnp(builtinsBuilder, CLOUDFLARE_BUNDLE); builder.add(builtinsBuilder.finish()); } } } // namespace workerd::api