File
Blob: src/workerd/api/commonjs.h
| 1 | #pragma once |
| 2 | |
| 3 | #include <workerd/jsg/jsg.h> |
| 4 | #include <workerd/jsg/url.h> |
| 5 | |
| 6 | #include <kj/filesystem.h> |
| 7 | |
| 8 | namespace workerd::api { |
| 9 | |
| 10 | class CommonJsModuleObject final: public jsg::Object { |
| 11 | public: |
| 12 | CommonJsModuleObject(jsg::Lock& js, kj::String path); |
| 13 | |
| 14 | jsg::JsValue getExports(jsg::Lock& js) const; |
| 15 | void setExports(jsg::Lock& js, jsg::JsValue value); |
| 16 | kj::StringPtr getPath() const; |
| 17 | |
| 18 | JSG_RESOURCE_TYPE(CommonJsModuleObject) { |
| 19 | JSG_INSTANCE_PROPERTY(exports, getExports, setExports); |
| 20 | JSG_LAZY_READONLY_INSTANCE_PROPERTY(path, getPath); |
| 21 | } |
| 22 | |
| 23 | void visitForMemoryInfo(jsg::MemoryTracker& tracker) const; |
| 24 | |
| 25 | private: |
| 26 | jsg::JsRef<jsg::JsValue> exports; |
| 27 | kj::String path; |
| 28 | }; |
| 29 | |
| 30 | class CommonJsModuleContext final: public jsg::Object { |
| 31 | public: |
| 32 | CommonJsModuleContext(jsg::Lock& js, kj::Path path); |
| 33 | CommonJsModuleContext(jsg::Lock& js, const jsg::Url& url); |
| 34 | |
| 35 | jsg::JsValue require(jsg::Lock& js, kj::String specifier); |
| 36 | |
| 37 | jsg::Ref<CommonJsModuleObject> getModule(jsg::Lock& js); |
| 38 | |
| 39 | jsg::JsValue getExports(jsg::Lock& js) const; |
| 40 | void setExports(jsg::Lock& js, jsg::JsValue value); |
| 41 | |
| 42 | kj::String getFilename() const; |
| 43 | kj::String getDirname() const; |
| 44 | |
| 45 | jsg::JsValue getModuleExports(jsg::Lock& js) { |
| 46 | return getModule(js)->getExports(js); |
| 47 | } |
| 48 | |
| 49 | JSG_RESOURCE_TYPE(CommonJsModuleContext) { |
| 50 | JSG_METHOD(require); |
| 51 | JSG_READONLY_INSTANCE_PROPERTY(module, getModule); |
| 52 | JSG_INSTANCE_PROPERTY(exports, getExports, setExports); |
| 53 | JSG_LAZY_INSTANCE_PROPERTY(__filename, getFilename); |
| 54 | JSG_LAZY_INSTANCE_PROPERTY(__dirname, getDirname); |
| 55 | } |
| 56 | |
| 57 | jsg::Ref<CommonJsModuleObject> module; |
| 58 | |
| 59 | void visitForMemoryInfo(jsg::MemoryTracker& tracker) const; |
| 60 | |
| 61 | private: |
| 62 | // If pathOrSpecifier is a path, then we're using the old module registry |
| 63 | // implementation. If it is a jsg::Url, then we are using the new module |
| 64 | // registry implementation. |
| 65 | kj::OneOf<kj::Path, jsg::Url> pathOrSpecifier; |
| 66 | jsg::JsRef<jsg::JsValue> exports; |
| 67 | }; |
| 68 | |
| 69 | // Used with the original module registry implementation. |
| 70 | template <typename LockType> |
| 71 | struct CommonJsImpl: public jsg::ModuleRegistry::CommonJsModuleInfo::CommonJsModuleProvider { |
| 72 | jsg::Ref<api::CommonJsModuleContext> context; |
| 73 | CommonJsImpl(jsg::Lock& js, kj::Path path) |
| 74 | : context(js.alloc<api::CommonJsModuleContext>(js, kj::mv(path))) {} |
| 75 | KJ_DISALLOW_COPY_AND_MOVE(CommonJsImpl); |
| 76 | jsg::JsObject getContext(jsg::Lock& js) override { |
| 77 | auto& lock = kj::downcast<LockType>(js); |
| 78 | return jsg::JsObject(lock.wrap(js.v8Context(), context.addRef())); |
| 79 | } |
| 80 | jsg::JsValue getExports(jsg::Lock& js) override { |
| 81 | return jsg::JsValue(context->getModule(js)->getExports(js)); |
| 82 | } |
| 83 | }; |
| 84 | |
| 85 | #define EW_CJS_ISOLATE_TYPES api::CommonJsModuleObject, api::CommonJsModuleContext |
| 86 | |
| 87 | } // namespace workerd::api |