#ifndef SRC_NODE_MODULES_H_ #define SRC_NODE_MODULES_H_ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include "node.h" #include "node_snapshotable.h" #include "simdjson.h" #include "util.h" #include "v8-fast-api-calls.h" #include "v8.h" #include #include #include #include #include namespace node { class ExternalReferenceRegistry; namespace modules { class BindingData : public SnapshotableObject { public: using InternalFieldInfo = InternalFieldInfoBase; struct PackageConfig { std::string file_path; std::optional name; std::optional main; std::string type = "none"; std::optional exports; std::optional imports; std::optional scripts; std::string raw_json; v8::Local Serialize(Realm* realm) const; }; struct ErrorContext { std::optional base; std::string specifier; bool is_esm; }; BindingData(Realm* realm, v8::Local obj, InternalFieldInfo* info = nullptr); SERIALIZABLE_OBJECT_METHODS() SET_BINDING_ID(modules_binding_data) void MemoryInfo(MemoryTracker* tracker) const override; SET_SELF_SIZE(BindingData) SET_MEMORY_INFO_NAME(BindingData) static void ReadPackageJSON(const v8::FunctionCallbackInfo& args); // Like ReadPackageJSON but the caller supplies the raw JSON body. // Does not populate the C++ `package_configs_` cache. // Signature: parsePackageJSON(source, jsonPath, isESM, base, specifier) static void ParsePackageJSONBinding( const v8::FunctionCallbackInfo& args); static void GetNearestParentPackageJSON( const v8::FunctionCallbackInfo& args); static void GetNearestParentPackageJSONType( const v8::FunctionCallbackInfo& args); template static void GetPackageScopeConfig( const v8::FunctionCallbackInfo& args); static void GetPackageJSONScripts( const v8::FunctionCallbackInfo& args); static void CreatePerIsolateProperties(IsolateData* isolate_data, v8::Local ctor); static void CreatePerContextProperties(v8::Local target, v8::Local unused, v8::Local context, void* priv); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); private: /* * This map caches `PackageConfig` values by `package.json` path. * An empty optional value indicates that no `package.json` file * at the given path exists, which we cache to avoid repeated * attempts to open the same non-existent paths. */ std::unordered_map > package_configs_; simdjson::ondemand::parser json_parser; static const std::filesystem::path NormalizePath(Realm* realm, BufferValue* path_value); // returns null on error static const PackageConfig* GetPackageJSON( Realm* realm, std::string_view path, ErrorContext* error_context = nullptr); // Parses `package_config->raw_json` into `package_config`; caller // must set raw_json and file_path first. Returns false and throws // ERR_INVALID_PACKAGE_CONFIG on a syntactic error. static bool ParsePackageJSON(Realm* realm, PackageConfig* package_config, ErrorContext* error_context); static const PackageConfig* TraverseParent( Realm* realm, const std::filesystem::path& check_path); }; } // namespace modules } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #endif // SRC_NODE_MODULES_H_