Skip to content
File

Blob: src/workerd/api/commonjs.h

cpp88 lines
1#pragma once
2 
3#include <workerd/jsg/jsg.h>
4#include <workerd/jsg/url.h>
5 
6#include <kj/filesystem.h>
7 
8namespace workerd::api {
9 
10class 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 
30class 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.
70template <typename LockType>
71struct 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