Browse Source

build: rework header generation in Node.js (#44657)

* build: rework header generation in Node.js

* build: fix patch location error

* fix: set --root-dir correctly
Shelley Vohr 5 months ago
parent
commit
7a5e9613d2

+ 12 - 18
BUILD.gn

@@ -1504,21 +1504,8 @@ group("electron") {
 ##### node_headers
 
 node_dir = "../third_party/electron_node"
-node_files = read_file("$node_dir/filenames.json", "json")
 node_headers_dir = "$root_gen_dir/node_headers"
 
-header_group_index = 0
-header_groups = []
-foreach(header_group, node_files.headers) {
-  copy("node_headers_${header_group_index}") {
-    sources = rebase_path(header_group.files, ".", node_dir)
-    outputs =
-        [ "$node_headers_dir/${header_group.dest_dir}/{{source_file_part}}" ]
-  }
-  header_groups += [ ":node_headers_${header_group_index}" ]
-  header_group_index += 1
-}
-
 copy("zlib_headers") {
   sources = [
     "$node_dir/deps/zlib/zconf.h",
@@ -1546,6 +1533,12 @@ action("node_version_header") {
   }
 }
 
+action("generate_node_headers") {
+  deps = [ ":generate_config_gypi" ]
+  script = "script/node/generate_node_headers.py"
+  outputs = [ "$root_gen_dir/node_headers.json" ]
+}
+
 action("tar_node_headers") {
   deps = [ ":copy_node_headers" ]
   outputs = [ "$root_gen_dir/node_headers.tar.gz" ]
@@ -1557,11 +1550,12 @@ action("tar_node_headers") {
 }
 
 group("copy_node_headers") {
-  public_deps = header_groups + [
-                  ":node_gypi_headers",
-                  ":node_version_header",
-                  ":zlib_headers",
-                ]
+  public_deps = [
+    ":generate_node_headers",
+    ":node_gypi_headers",
+    ":node_version_header",
+    ":zlib_headers",
+  ]
 }
 
 group("node_headers") {

+ 2 - 2
patches/chromium/refactor_unfilter_unresponsive_events.patch

@@ -15,10 +15,10 @@ This CL removes these filters so the unresponsive event can still be
 accessed from our JS event. The filtering is moved into Electron's code.
 
 diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
-index 319800cec84a968b0e442fc760c8e1d701bda2ed..459663af86272fe1e23a6a163e01c67fc5f8a66d 100644
+index 0e742f196367bbbe8c4e147ef4db4f8dbbe4cbbe..7026b28c4f228971f74a706b6ad99777e4ca0773 100644
 --- a/content/browser/web_contents/web_contents_impl.cc
 +++ b/content/browser/web_contents/web_contents_impl.cc
-@@ -9464,25 +9464,13 @@ void WebContentsImpl::RendererUnresponsive(
+@@ -9518,25 +9518,13 @@ void WebContentsImpl::RendererUnresponsive(
      base::RepeatingClosure hang_monitor_restarter) {
    OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RendererUnresponsive",
                          "render_widget_host", render_widget_host);

+ 9 - 922
patches/node/build_add_gn_build_files.patch

@@ -10,32 +10,6 @@ however those files were cherry-picked from main branch and do not
 really in 20/21. We have to wait until 22 is released to be able to
 build with upstream GN files.
 
-diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h
-index 60bfce3ea8999e8e145aaf8cd14f0fdf21ed9c54..661c996889d0a89c1c38658a0933fcf5e3cdc1b9 100644
---- a/deps/ncrypto/ncrypto.h
-+++ b/deps/ncrypto/ncrypto.h
-@@ -400,17 +400,21 @@ public:
-     UNABLE_TO_CHECK_GENERATOR = DH_UNABLE_TO_CHECK_GENERATOR,
-     NOT_SUITABLE_GENERATOR = DH_NOT_SUITABLE_GENERATOR,
-     Q_NOT_PRIME = DH_CHECK_Q_NOT_PRIME,
-+#ifndef OPENSSL_IS_BORINGSSL
-     INVALID_Q = DH_CHECK_INVALID_Q_VALUE,
-     INVALID_J = DH_CHECK_INVALID_J_VALUE,
-+#endif
-     CHECK_FAILED = 512,
-   };
-   CheckResult check();
- 
-   enum class CheckPublicKeyResult {
-     NONE,
-+  #ifndef OPENSSL_IS_BORINGSSL
-     TOO_SMALL = DH_R_CHECK_PUBKEY_TOO_SMALL,
-     TOO_LARGE = DH_R_CHECK_PUBKEY_TOO_LARGE,
-     INVALID = DH_R_CHECK_PUBKEY_INVALID,
-+  #endif
-     CHECK_FAILED = 512,
-   };
-   // Check to see if the given public key is suitable for this DH instance.
 diff --git a/deps/sqlite/unofficial.gni b/deps/sqlite/unofficial.gni
 index ebb3ffcd6d42b4c16b6865a91ccf4428cffe864b..00225afa1fb4205f1e02d9f185aeb97d642b3fd9 100644
 --- a/deps/sqlite/unofficial.gni
@@ -56,768 +30,6 @@ index ebb3ffcd6d42b4c16b6865a91ccf4428cffe864b..00225afa1fb4205f1e02d9f185aeb97d
          "-Wno-sign-compare",
          "-Wno-unused-but-set-variable",
          "-Wno-unused-function",
-diff --git a/filenames.json b/filenames.json
-new file mode 100644
-index 0000000000000000000000000000000000000000..5af3886d8d3d74d31249a4d79030a8373b8dad52
---- /dev/null
-+++ b/filenames.json
-@@ -0,0 +1,756 @@
-+// This file is automatically generated by generate_gn_filenames_json.py
-+// DO NOT EDIT
-+{
-+  "fs_files": [
-+    "lib/internal/fs/cp/cp-sync.js",
-+    "lib/internal/fs/cp/cp.js",
-+    "lib/internal/fs/dir.js",
-+    "lib/internal/fs/glob.js",
-+    "lib/internal/fs/promises.js",
-+    "lib/internal/fs/read/context.js",
-+    "lib/internal/fs/recursive_watch.js",
-+    "lib/internal/fs/rimraf.js",
-+    "lib/internal/fs/streams.js",
-+    "lib/internal/fs/sync_write_stream.js",
-+    "lib/internal/fs/utils.js",
-+    "lib/internal/fs/watchers.js",
-+    "lib/fs.js",
-+    "lib/fs/promises.js"
-+  ],
-+  "headers": [
-+    {
-+      "dest_dir": "include/node/",
-+      "files": [
-+        "src/js_native_api.h",
-+        "src/js_native_api_types.h",
-+        "src/node.h",
-+        "src/node_api.h",
-+        "src/node_api_types.h",
-+        "src/node_buffer.h",
-+        "src/node_object_wrap.h"
-+      ]
-+    },
-+    {
-+      "dest_dir": "include/node/./",
-+      "files": [
-+        "//v8/include/v8-array-buffer.h",
-+        "//v8/include/v8-callbacks.h",
-+        "//v8/include/v8-container.h",
-+        "//v8/include/v8-context.h",
-+        "//v8/include/v8-cppgc.h",
-+        "//v8/include/v8-data.h",
-+        "//v8/include/v8-date.h",
-+        "//v8/include/v8-debug.h",
-+        "//v8/include/v8-embedder-heap.h",
-+        "//v8/include/v8-embedder-state-scope.h",
-+        "//v8/include/v8-exception.h",
-+        "//v8/include/v8-extension.h",
-+        "//v8/include/v8-external.h",
-+        "//v8/include/v8-forward.h",
-+        "//v8/include/v8-function-callback.h",
-+        "//v8/include/v8-function.h",
-+        "//v8/include/v8-handle-base.h",
-+        "//v8/include/v8-initialization.h",
-+        "//v8/include/v8-internal.h",
-+        "//v8/include/v8-isolate.h",
-+        "//v8/include/v8-json.h",
-+        "//v8/include/v8-local-handle.h",
-+        "//v8/include/v8-locker.h",
-+        "//v8/include/v8-maybe.h",
-+        "//v8/include/v8-memory-span.h",
-+        "//v8/include/v8-message.h",
-+        "//v8/include/v8-microtask-queue.h",
-+        "//v8/include/v8-microtask.h",
-+        "//v8/include/v8-object.h",
-+        "//v8/include/v8-persistent-handle.h",
-+        "//v8/include/v8-platform.h",
-+        "//v8/include/v8-primitive-object.h",
-+        "//v8/include/v8-primitive.h",
-+        "//v8/include/v8-profiler.h",
-+        "//v8/include/v8-promise.h",
-+        "//v8/include/v8-proxy.h",
-+        "//v8/include/v8-regexp.h",
-+        "//v8/include/v8-sandbox.h",
-+        "//v8/include/v8-script.h",
-+        "//v8/include/v8-snapshot.h",
-+        "//v8/include/v8-source-location.h",
-+        "//v8/include/v8-statistics.h",
-+        "//v8/include/v8-template.h",
-+        "//v8/include/v8-traced-handle.h",
-+        "//v8/include/v8-typed-array.h",
-+        "//v8/include/v8-unwinder.h",
-+        "//v8/include/v8-value-serializer.h",
-+        "//v8/include/v8-value.h",
-+        "//v8/include/v8-version.h",
-+        "//v8/include/v8-wasm.h",
-+        "//v8/include/v8-weak-callback-info.h",
-+        "//v8/include/v8.h",
-+        "//v8/include/v8config.h",
-+        "deps/uv/include/uv.h"
-+      ]
-+    },
-+    {
-+      "dest_dir": "include/node/libplatform/",
-+      "files": [
-+        "//v8/include/libplatform/libplatform-export.h",
-+        "//v8/include/libplatform/libplatform.h",
-+        "//v8/include/libplatform/v8-tracing.h"
-+      ]
-+    },
-+    {
-+      "dest_dir": "include/node/cppgc/",
-+      "files": [
-+        "//v8/include/cppgc/allocation.h",
-+        "//v8/include/cppgc/common.h",
-+        "//v8/include/cppgc/cross-thread-persistent.h",
-+        "//v8/include/cppgc/custom-space.h",
-+        "//v8/include/cppgc/default-platform.h",
-+        "//v8/include/cppgc/ephemeron-pair.h",
-+        "//v8/include/cppgc/explicit-management.h",
-+        "//v8/include/cppgc/garbage-collected.h",
-+        "//v8/include/cppgc/heap-consistency.h",
-+        "//v8/include/cppgc/heap-handle.h",
-+        "//v8/include/cppgc/heap-state.h",
-+        "//v8/include/cppgc/heap-statistics.h",
-+        "//v8/include/cppgc/heap.h",
-+        "//v8/include/cppgc/liveness-broker.h",
-+        "//v8/include/cppgc/macros.h",
-+        "//v8/include/cppgc/member.h",
-+        "//v8/include/cppgc/name-provider.h",
-+        "//v8/include/cppgc/object-size-trait.h",
-+        "//v8/include/cppgc/persistent.h",
-+        "//v8/include/cppgc/platform.h",
-+        "//v8/include/cppgc/prefinalizer.h",
-+        "//v8/include/cppgc/process-heap-statistics.h",
-+        "//v8/include/cppgc/sentinel-pointer.h",
-+        "//v8/include/cppgc/source-location.h",
-+        "//v8/include/cppgc/testing.h",
-+        "//v8/include/cppgc/trace-trait.h",
-+        "//v8/include/cppgc/type-traits.h",
-+        "//v8/include/cppgc/visitor.h"
-+      ]
-+    },
-+    {
-+      "dest_dir": "include/node/cppgc/internal/",
-+      "files": [
-+        "//v8/include/cppgc/internal/api-constants.h",
-+        "//v8/include/cppgc/internal/atomic-entry-flag.h",
-+        "//v8/include/cppgc/internal/base-page-handle.h",
-+        "//v8/include/cppgc/internal/caged-heap-local-data.h",
-+        "//v8/include/cppgc/internal/caged-heap.h",
-+        "//v8/include/cppgc/internal/compiler-specific.h",
-+        "//v8/include/cppgc/internal/finalizer-trait.h",
-+        "//v8/include/cppgc/internal/gc-info.h",
-+        "//v8/include/cppgc/internal/logging.h",
-+        "//v8/include/cppgc/internal/member-storage.h",
-+        "//v8/include/cppgc/internal/name-trait.h",
-+        "//v8/include/cppgc/internal/persistent-node.h",
-+        "//v8/include/cppgc/internal/pointer-policies.h",
-+        "//v8/include/cppgc/internal/write-barrier.h"
-+      ]
-+    },
-+    {
-+      "dest_dir": "include/node/uv/",
-+      "files": [
-+        "deps/uv/include/uv/aix.h",
-+        "deps/uv/include/uv/bsd.h",
-+        "deps/uv/include/uv/darwin.h",
-+        "deps/uv/include/uv/errno.h",
-+        "deps/uv/include/uv/linux.h",
-+        "deps/uv/include/uv/os390.h",
-+        "deps/uv/include/uv/posix.h",
-+        "deps/uv/include/uv/sunos.h",
-+        "deps/uv/include/uv/threadpool.h",
-+        "deps/uv/include/uv/tree.h",
-+        "deps/uv/include/uv/unix.h",
-+        "deps/uv/include/uv/version.h",
-+        "deps/uv/include/uv/win.h"
-+      ]
-+    }
-+  ],
-+  "library_files": [
-+    "lib/_http_agent.js",
-+    "lib/_http_client.js",
-+    "lib/_http_common.js",
-+    "lib/_http_incoming.js",
-+    "lib/_http_outgoing.js",
-+    "lib/_http_server.js",
-+    "lib/_stream_duplex.js",
-+    "lib/_stream_passthrough.js",
-+    "lib/_stream_readable.js",
-+    "lib/_stream_transform.js",
-+    "lib/_stream_wrap.js",
-+    "lib/_stream_writable.js",
-+    "lib/_tls_common.js",
-+    "lib/_tls_wrap.js",
-+    "lib/assert.js",
-+    "lib/assert/strict.js",
-+    "lib/async_hooks.js",
-+    "lib/buffer.js",
-+    "lib/child_process.js",
-+    "lib/cluster.js",
-+    "lib/console.js",
-+    "lib/constants.js",
-+    "lib/crypto.js",
-+    "lib/dgram.js",
-+    "lib/diagnostics_channel.js",
-+    "lib/dns.js",
-+    "lib/dns/promises.js",
-+    "lib/domain.js",
-+    "lib/events.js",
-+    "lib/http.js",
-+    "lib/http2.js",
-+    "lib/https.js",
-+    "lib/inspector.js",
-+    "lib/inspector/promises.js",
-+    "lib/internal/abort_controller.js",
-+    "lib/internal/assert.js",
-+    "lib/internal/assert/assertion_error.js",
-+    "lib/internal/assert/calltracker.js",
-+    "lib/internal/assert/utils.js",
-+    "lib/internal/async_context_frame.js",
-+    "lib/internal/async_hooks.js",
-+    "lib/internal/async_local_storage/async_context_frame.js",
-+    "lib/internal/async_local_storage/async_hooks.js",
-+    "lib/internal/blob.js",
-+    "lib/internal/blocklist.js",
-+    "lib/internal/bootstrap/node.js",
-+    "lib/internal/bootstrap/realm.js",
-+    "lib/internal/bootstrap/shadow_realm.js",
-+    "lib/internal/bootstrap/switches/does_not_own_process_state.js",
-+    "lib/internal/bootstrap/switches/does_own_process_state.js",
-+    "lib/internal/bootstrap/switches/is_main_thread.js",
-+    "lib/internal/bootstrap/switches/is_not_main_thread.js",
-+    "lib/internal/bootstrap/web/exposed-wildcard.js",
-+    "lib/internal/bootstrap/web/exposed-window-or-worker.js",
-+    "lib/internal/buffer.js",
-+    "lib/internal/child_process.js",
-+    "lib/internal/child_process/serialization.js",
-+    "lib/internal/cli_table.js",
-+    "lib/internal/cluster/child.js",
-+    "lib/internal/cluster/primary.js",
-+    "lib/internal/cluster/round_robin_handle.js",
-+    "lib/internal/cluster/shared_handle.js",
-+    "lib/internal/cluster/utils.js",
-+    "lib/internal/cluster/worker.js",
-+    "lib/internal/console/constructor.js",
-+    "lib/internal/console/global.js",
-+    "lib/internal/constants.js",
-+    "lib/internal/crypto/aes.js",
-+    "lib/internal/crypto/certificate.js",
-+    "lib/internal/crypto/cfrg.js",
-+    "lib/internal/crypto/cipher.js",
-+    "lib/internal/crypto/diffiehellman.js",
-+    "lib/internal/crypto/ec.js",
-+    "lib/internal/crypto/hash.js",
-+    "lib/internal/crypto/hashnames.js",
-+    "lib/internal/crypto/hkdf.js",
-+    "lib/internal/crypto/keygen.js",
-+    "lib/internal/crypto/keys.js",
-+    "lib/internal/crypto/mac.js",
-+    "lib/internal/crypto/pbkdf2.js",
-+    "lib/internal/crypto/random.js",
-+    "lib/internal/crypto/rsa.js",
-+    "lib/internal/crypto/scrypt.js",
-+    "lib/internal/crypto/sig.js",
-+    "lib/internal/crypto/util.js",
-+    "lib/internal/crypto/webcrypto.js",
-+    "lib/internal/crypto/webidl.js",
-+    "lib/internal/crypto/x509.js",
-+    "lib/internal/data_url.js",
-+    "lib/internal/debugger/inspect.js",
-+    "lib/internal/debugger/inspect_client.js",
-+    "lib/internal/debugger/inspect_repl.js",
-+    "lib/internal/dgram.js",
-+    "lib/internal/dns/callback_resolver.js",
-+    "lib/internal/dns/promises.js",
-+    "lib/internal/dns/utils.js",
-+    "lib/internal/encoding.js",
-+    "lib/internal/error_serdes.js",
-+    "lib/internal/errors.js",
-+    "lib/internal/event_target.js",
-+    "lib/internal/events/abort_listener.js",
-+    "lib/internal/events/symbols.js",
-+    "lib/internal/file.js",
-+    "lib/internal/fixed_queue.js",
-+    "lib/internal/freelist.js",
-+    "lib/internal/freeze_intrinsics.js",
-+    "lib/internal/heap_utils.js",
-+    "lib/internal/histogram.js",
-+    "lib/internal/http.js",
-+    "lib/internal/http2/compat.js",
-+    "lib/internal/http2/core.js",
-+    "lib/internal/http2/util.js",
-+    "lib/internal/idna.js",
-+    "lib/internal/inspector_async_hook.js",
-+    "lib/internal/inspector_network_tracking.js",
-+    "lib/internal/js_stream_socket.js",
-+    "lib/internal/legacy/processbinding.js",
-+    "lib/internal/linkedlist.js",
-+    "lib/internal/main/check_syntax.js",
-+    "lib/internal/main/embedding.js",
-+    "lib/internal/main/eval_stdin.js",
-+    "lib/internal/main/eval_string.js",
-+    "lib/internal/main/inspect.js",
-+    "lib/internal/main/mksnapshot.js",
-+    "lib/internal/main/print_help.js",
-+    "lib/internal/main/prof_process.js",
-+    "lib/internal/main/repl.js",
-+    "lib/internal/main/run_main_module.js",
-+    "lib/internal/main/test_runner.js",
-+    "lib/internal/main/watch_mode.js",
-+    "lib/internal/main/worker_thread.js",
-+    "lib/internal/mime.js",
-+    "lib/internal/modules/cjs/loader.js",
-+    "lib/internal/modules/esm/assert.js",
-+    "lib/internal/modules/esm/create_dynamic_module.js",
-+    "lib/internal/modules/esm/fetch_module.js",
-+    "lib/internal/modules/esm/formats.js",
-+    "lib/internal/modules/esm/get_format.js",
-+    "lib/internal/modules/esm/hooks.js",
-+    "lib/internal/modules/esm/initialize_import_meta.js",
-+    "lib/internal/modules/esm/load.js",
-+    "lib/internal/modules/esm/loader.js",
-+    "lib/internal/modules/esm/module_job.js",
-+    "lib/internal/modules/esm/module_map.js",
-+    "lib/internal/modules/esm/resolve.js",
-+    "lib/internal/modules/esm/shared_constants.js",
-+    "lib/internal/modules/esm/translators.js",
-+    "lib/internal/modules/esm/utils.js",
-+    "lib/internal/modules/esm/worker.js",
-+    "lib/internal/modules/helpers.js",
-+    "lib/internal/modules/package_json_reader.js",
-+    "lib/internal/modules/run_main.js",
-+    "lib/internal/navigator.js",
-+    "lib/internal/net.js",
-+    "lib/internal/options.js",
-+    "lib/internal/per_context/domexception.js",
-+    "lib/internal/per_context/messageport.js",
-+    "lib/internal/per_context/primordials.js",
-+    "lib/internal/perf/event_loop_delay.js",
-+    "lib/internal/perf/event_loop_utilization.js",
-+    "lib/internal/perf/nodetiming.js",
-+    "lib/internal/perf/observe.js",
-+    "lib/internal/perf/performance.js",
-+    "lib/internal/perf/performance_entry.js",
-+    "lib/internal/perf/resource_timing.js",
-+    "lib/internal/perf/timerify.js",
-+    "lib/internal/perf/usertiming.js",
-+    "lib/internal/perf/utils.js",
-+    "lib/internal/priority_queue.js",
-+    "lib/internal/process/execution.js",
-+    "lib/internal/process/finalization.js",
-+    "lib/internal/process/per_thread.js",
-+    "lib/internal/process/permission.js",
-+    "lib/internal/process/pre_execution.js",
-+    "lib/internal/process/promises.js",
-+    "lib/internal/process/report.js",
-+    "lib/internal/process/signal.js",
-+    "lib/internal/process/task_queues.js",
-+    "lib/internal/process/warning.js",
-+    "lib/internal/process/worker_thread_only.js",
-+    "lib/internal/promise_hooks.js",
-+    "lib/internal/querystring.js",
-+    "lib/internal/readline/callbacks.js",
-+    "lib/internal/readline/emitKeypressEvents.js",
-+    "lib/internal/readline/interface.js",
-+    "lib/internal/readline/promises.js",
-+    "lib/internal/readline/utils.js",
-+    "lib/internal/repl.js",
-+    "lib/internal/repl/await.js",
-+    "lib/internal/repl/history.js",
-+    "lib/internal/repl/utils.js",
-+    "lib/internal/socket_list.js",
-+    "lib/internal/socketaddress.js",
-+    "lib/internal/source_map/prepare_stack_trace.js",
-+    "lib/internal/source_map/source_map.js",
-+    "lib/internal/source_map/source_map_cache.js",
-+    "lib/internal/source_map/source_map_cache_map.js",
-+    "lib/internal/stream_base_commons.js",
-+    "lib/internal/streams/add-abort-signal.js",
-+    "lib/internal/streams/compose.js",
-+    "lib/internal/streams/destroy.js",
-+    "lib/internal/streams/duplex.js",
-+    "lib/internal/streams/duplexify.js",
-+    "lib/internal/streams/duplexpair.js",
-+    "lib/internal/streams/end-of-stream.js",
-+    "lib/internal/streams/from.js",
-+    "lib/internal/streams/lazy_transform.js",
-+    "lib/internal/streams/legacy.js",
-+    "lib/internal/streams/operators.js",
-+    "lib/internal/streams/passthrough.js",
-+    "lib/internal/streams/pipeline.js",
-+    "lib/internal/streams/readable.js",
-+    "lib/internal/streams/state.js",
-+    "lib/internal/streams/transform.js",
-+    "lib/internal/streams/utils.js",
-+    "lib/internal/streams/writable.js",
-+    "lib/internal/test/binding.js",
-+    "lib/internal/test/transfer.js",
-+    "lib/internal/test_runner/coverage.js",
-+    "lib/internal/test_runner/harness.js",
-+    "lib/internal/test_runner/mock/loader.js",
-+    "lib/internal/test_runner/mock/mock.js",
-+    "lib/internal/test_runner/mock/mock_timers.js",
-+    "lib/internal/test_runner/reporter/dot.js",
-+    "lib/internal/test_runner/reporter/junit.js",
-+    "lib/internal/test_runner/reporter/lcov.js",
-+    "lib/internal/test_runner/reporter/spec.js",
-+    "lib/internal/test_runner/reporter/tap.js",
-+    "lib/internal/test_runner/reporter/utils.js",
-+    "lib/internal/test_runner/reporter/v8-serializer.js",
-+    "lib/internal/test_runner/runner.js",
-+    "lib/internal/test_runner/snapshot.js",
-+    "lib/internal/test_runner/test.js",
-+    "lib/internal/test_runner/tests_stream.js",
-+    "lib/internal/test_runner/utils.js",
-+    "lib/internal/timers.js",
-+    "lib/internal/tls/secure-context.js",
-+    "lib/internal/tls/secure-pair.js",
-+    "lib/internal/trace_events_async_hooks.js",
-+    "lib/internal/tty.js",
-+    "lib/internal/url.js",
-+    "lib/internal/util.js",
-+    "lib/internal/util/colors.js",
-+    "lib/internal/util/comparisons.js",
-+    "lib/internal/util/debuglog.js",
-+    "lib/internal/util/inspect.js",
-+    "lib/internal/util/inspector.js",
-+    "lib/internal/util/parse_args/parse_args.js",
-+    "lib/internal/util/parse_args/utils.js",
-+    "lib/internal/util/types.js",
-+    "lib/internal/v8/startup_snapshot.js",
-+    "lib/internal/v8_prof_polyfill.js",
-+    "lib/internal/v8_prof_processor.js",
-+    "lib/internal/validators.js",
-+    "lib/internal/vm.js",
-+    "lib/internal/vm/module.js",
-+    "lib/internal/wasm_web_api.js",
-+    "lib/internal/watch_mode/files_watcher.js",
-+    "lib/internal/watchdog.js",
-+    "lib/internal/webidl.js",
-+    "lib/internal/webstorage.js",
-+    "lib/internal/webstreams/adapters.js",
-+    "lib/internal/webstreams/compression.js",
-+    "lib/internal/webstreams/encoding.js",
-+    "lib/internal/webstreams/queuingstrategies.js",
-+    "lib/internal/webstreams/readablestream.js",
-+    "lib/internal/webstreams/transfer.js",
-+    "lib/internal/webstreams/transformstream.js",
-+    "lib/internal/webstreams/util.js",
-+    "lib/internal/webstreams/writablestream.js",
-+    "lib/internal/worker.js",
-+    "lib/internal/worker/io.js",
-+    "lib/internal/worker/js_transferable.js",
-+    "lib/internal/worker/messaging.js",
-+    "lib/module.js",
-+    "lib/net.js",
-+    "lib/os.js",
-+    "lib/path.js",
-+    "lib/path/posix.js",
-+    "lib/path/win32.js",
-+    "lib/perf_hooks.js",
-+    "lib/process.js",
-+    "lib/punycode.js",
-+    "lib/querystring.js",
-+    "lib/readline.js",
-+    "lib/readline/promises.js",
-+    "lib/repl.js",
-+    "lib/sea.js",
-+    "lib/sqlite.js",
-+    "lib/stream.js",
-+    "lib/stream/consumers.js",
-+    "lib/stream/promises.js",
-+    "lib/stream/web.js",
-+    "lib/string_decoder.js",
-+    "lib/sys.js",
-+    "lib/test.js",
-+    "lib/test/reporters.js",
-+    "lib/timers.js",
-+    "lib/timers/promises.js",
-+    "lib/tls.js",
-+    "lib/trace_events.js",
-+    "lib/tty.js",
-+    "lib/url.js",
-+    "lib/util.js",
-+    "lib/util/types.js",
-+    "lib/v8.js",
-+    "lib/vm.js",
-+    "lib/wasi.js",
-+    "lib/worker_threads.js",
-+    "lib/zlib.js",
-+    "deps/v8/tools/splaytree.mjs",
-+    "deps/v8/tools/codemap.mjs",
-+    "deps/v8/tools/consarray.mjs",
-+    "deps/v8/tools/csvparser.mjs",
-+    "deps/v8/tools/profile.mjs",
-+    "deps/v8/tools/profile_view.mjs",
-+    "deps/v8/tools/logreader.mjs",
-+    "deps/v8/tools/arguments.mjs",
-+    "deps/v8/tools/tickprocessor.mjs",
-+    "deps/v8/tools/sourcemap.mjs",
-+    "deps/v8/tools/tickprocessor-driver.mjs",
-+    "deps/acorn/acorn/dist/acorn.js",
-+    "deps/acorn/acorn-walk/dist/walk.js",
-+    "deps/minimatch/index.js",
-+    "deps/cjs-module-lexer/lexer.js",
-+    "deps/cjs-module-lexer/dist/lexer.js",
-+    "deps/undici/undici.js"
-+  ],
-+  "node_sources": [
-+    "src/api/async_resource.cc",
-+    "src/api/callback.cc",
-+    "src/api/embed_helpers.cc",
-+    "src/api/encoding.cc",
-+    "src/api/environment.cc",
-+    "src/api/exceptions.cc",
-+    "src/api/hooks.cc",
-+    "src/api/utils.cc",
-+    "src/async_context_frame.cc",
-+    "src/async_wrap.cc",
-+    "src/base_object.cc",
-+    "src/cares_wrap.cc",
-+    "src/cleanup_queue.cc",
-+    "src/compile_cache.cc",
-+    "src/connect_wrap.cc",
-+    "src/connection_wrap.cc",
-+    "src/dataqueue/queue.cc",
-+    "src/debug_utils.cc",
-+    "src/embedded_data.cc",
-+    "src/encoding_binding.cc",
-+    "src/env.cc",
-+    "src/fs_event_wrap.cc",
-+    "src/handle_wrap.cc",
-+    "src/heap_utils.cc",
-+    "src/histogram.cc",
-+    "src/internal_only_v8.cc",
-+    "src/js_native_api.h",
-+    "src/js_native_api_types.h",
-+    "src/js_native_api_v8.cc",
-+    "src/js_native_api_v8.h",
-+    "src/js_native_api_v8_internals.h",
-+    "src/js_stream.cc",
-+    "src/json_utils.cc",
-+    "src/js_udp_wrap.cc",
-+    "src/json_parser.h",
-+    "src/json_parser.cc",
-+    "src/module_wrap.cc",
-+    "src/node.cc",
-+    "src/node_api.cc",
-+    "src/node_binding.cc",
-+    "src/node_blob.cc",
-+    "src/node_buffer.cc",
-+    "src/node_builtins.cc",
-+    "src/node_config.cc",
-+    "src/node_constants.cc",
-+    "src/node_contextify.cc",
-+    "src/node_credentials.cc",
-+    "src/node_debug.cc",
-+    "src/node_dir.cc",
-+    "src/node_dotenv.cc",
-+    "src/node_env_var.cc",
-+    "src/node_errors.cc",
-+    "src/node_external_reference.cc",
-+    "src/node_file.cc",
-+    "src/node_http_parser.cc",
-+    "src/node_http2.cc",
-+    "src/node_i18n.cc",
-+    "src/node_main_instance.cc",
-+    "src/node_messaging.cc",
-+    "src/node_metadata.cc",
-+    "src/node_modules.cc",
-+    "src/node_options.cc",
-+    "src/node_os.cc",
-+    "src/node_perf.cc",
-+    "src/node_platform.cc",
-+    "src/node_postmortem_metadata.cc",
-+    "src/node_process_events.cc",
-+    "src/node_process_methods.cc",
-+    "src/node_process_object.cc",
-+    "src/node_realm.cc",
-+    "src/node_report.cc",
-+    "src/node_report_module.cc",
-+    "src/node_report_utils.cc",
-+    "src/node_sea.cc",
-+    "src/node_serdes.cc",
-+    "src/node_shadow_realm.cc",
-+    "src/node_snapshotable.cc",
-+    "src/node_sockaddr.cc",
-+    "src/node_sqlite.cc",
-+    "src/node_stat_watcher.cc",
-+    "src/node_symbols.cc",
-+    "src/node_task_queue.cc",
-+    "src/node_task_runner.cc",
-+    "src/node_trace_events.cc",
-+    "src/node_types.cc",
-+    "src/node_url.cc",
-+    "src/node_util.cc",
-+    "src/node_v8.cc",
-+    "src/node_wasi.cc",
-+    "src/node_wasm_web_api.cc",
-+    "src/node_watchdog.cc",
-+    "src/node_webstorage.cc",
-+    "src/node_worker.cc",
-+    "src/node_zlib.cc",
-+    "src/path.cc",
-+    "src/permission/child_process_permission.cc",
-+    "src/permission/fs_permission.cc",
-+    "src/permission/inspector_permission.cc",
-+    "src/permission/permission.cc",
-+    "src/permission/wasi_permission.cc",
-+    "src/permission/worker_permission.cc",
-+    "src/pipe_wrap.cc",
-+    "src/process_wrap.cc",
-+    "src/signal_wrap.cc",
-+    "src/spawn_sync.cc",
-+    "src/stream_base.cc",
-+    "src/stream_pipe.cc",
-+    "src/stream_wrap.cc",
-+    "src/string_bytes.cc",
-+    "src/string_decoder.cc",
-+    "src/tcp_wrap.cc",
-+    "src/timers.cc",
-+    "src/timer_wrap.cc",
-+    "src/tracing/agent.cc",
-+    "src/tracing/node_trace_buffer.cc",
-+    "src/tracing/node_trace_writer.cc",
-+    "src/tracing/trace_event.cc",
-+    "src/tracing/traced_value.cc",
-+    "src/tty_wrap.cc",
-+    "src/udp_wrap.cc",
-+    "src/util.cc",
-+    "src/uv.cc",
-+    "src/aliased_buffer.h",
-+    "src/aliased_buffer-inl.h",
-+    "src/aliased_struct.h",
-+    "src/aliased_struct-inl.h",
-+    "src/async_context_frame.h",
-+    "src/async_wrap.h",
-+    "src/async_wrap-inl.h",
-+    "src/base_object.h",
-+    "src/base_object-inl.h",
-+    "src/base_object_types.h",
-+    "src/blob_serializer_deserializer.h",
-+    "src/blob_serializer_deserializer-inl.h",
-+    "src/callback_queue.h",
-+    "src/callback_queue-inl.h",
-+    "src/cleanup_queue.h",
-+    "src/cleanup_queue-inl.h",
-+    "src/compile_cache.h",
-+    "src/connect_wrap.h",
-+    "src/connection_wrap.h",
-+    "src/dataqueue/queue.h",
-+    "src/debug_utils.h",
-+    "src/debug_utils-inl.h",
-+    "src/embedded_data.h",
-+    "src/encoding_binding.h",
-+    "src/env_properties.h",
-+    "src/env.h",
-+    "src/env-inl.h",
-+    "src/handle_wrap.h",
-+    "src/histogram.h",
-+    "src/histogram-inl.h",
-+    "src/js_stream.h",
-+    "src/json_utils.h",
-+    "src/large_pages/node_large_page.cc",
-+    "src/large_pages/node_large_page.h",
-+    "src/memory_tracker.h",
-+    "src/memory_tracker-inl.h",
-+    "src/module_wrap.h",
-+    "src/node.h",
-+    "src/node_api.h",
-+    "src/node_api_types.h",
-+    "src/node_binding.h",
-+    "src/node_blob.h",
-+    "src/node_buffer.h",
-+    "src/node_builtins.h",
-+    "src/node_constants.h",
-+    "src/node_context_data.h",
-+    "src/node_contextify.h",
-+    "src/node_debug.h",
-+    "src/node_dir.h",
-+    "src/node_dotenv.h",
-+    "src/node_errors.h",
-+    "src/node_exit_code.h",
-+    "src/node_external_reference.h",
-+    "src/node_file.h",
-+    "src/node_file-inl.h",
-+    "src/node_http_common.h",
-+    "src/node_http_common-inl.h",
-+    "src/node_http2.h",
-+    "src/node_http2_state.h",
-+    "src/node_i18n.h",
-+    "src/node_internals.h",
-+    "src/node_main_instance.h",
-+    "src/node_mem.h",
-+    "src/node_mem-inl.h",
-+    "src/node_messaging.h",
-+    "src/node_metadata.h",
-+    "src/node_mutex.h",
-+    "src/node_modules.h",
-+    "src/node_object_wrap.h",
-+    "src/node_options.h",
-+    "src/node_options-inl.h",
-+    "src/node_perf.h",
-+    "src/node_perf_common.h",
-+    "src/node_platform.h",
-+    "src/node_process.h",
-+    "src/node_process-inl.h",
-+    "src/node_realm.h",
-+    "src/node_realm-inl.h",
-+    "src/node_report.h",
-+    "src/node_revert.h",
-+    "src/node_root_certs.h",
-+    "src/node_sea.h",
-+    "src/node_shadow_realm.h",
-+    "src/node_snapshotable.h",
-+    "src/node_snapshot_builder.h",
-+    "src/node_sockaddr.h",
-+    "src/node_sockaddr-inl.h",
-+    "src/node_sqlite.h",
-+    "src/node_stat_watcher.h",
-+    "src/node_union_bytes.h",
-+    "src/node_url.h",
-+    "src/node_version.h",
-+    "src/node_v8.h",
-+    "src/node_v8_platform-inl.h",
-+    "src/node_wasi.h",
-+    "src/node_watchdog.h",
-+    "src/node_webstorage.h",
-+    "src/node_worker.h",
-+    "src/path.h",
-+    "src/permission/child_process_permission.h",
-+    "src/permission/fs_permission.h",
-+    "src/permission/inspector_permission.h",
-+    "src/permission/permission.h",
-+    "src/permission/wasi_permission.h",
-+    "src/permission/worker_permission.h",
-+    "src/pipe_wrap.h",
-+    "src/req_wrap.h",
-+    "src/req_wrap-inl.h",
-+    "src/spawn_sync.h",
-+    "src/stream_base.h",
-+    "src/stream_base-inl.h",
-+    "src/stream_pipe.h",
-+    "src/stream_wrap.h",
-+    "src/string_bytes.h",
-+    "src/string_decoder.h",
-+    "src/string_decoder-inl.h",
-+    "src/tcp_wrap.h",
-+    "src/timers.h",
-+    "src/tracing/agent.h",
-+    "src/tracing/node_trace_buffer.h",
-+    "src/tracing/node_trace_writer.h",
-+    "src/tracing/trace_event.h",
-+    "src/tracing/trace_event_common.h",
-+    "src/tracing/traced_value.h",
-+    "src/timer_wrap.h",
-+    "src/timer_wrap-inl.h",
-+    "src/tty_wrap.h",
-+    "src/udp_wrap.h",
-+    "src/util.h",
-+    "src/util-inl.h",
-+    "//v8/include/v8.h",
-+    "deps/postject/postject-api.h"
-+  ]
-+}
 diff --git a/node.gni b/node.gni
 index 9dca810decebd75aab427e306b3cc37c80fb55c9..32709b860ccb12d8d1e75342a65dda0b86129b21 100644
 --- a/node.gni
@@ -891,143 +103,18 @@ index 45b3ac5006140fb55aad0e6b78084b753a947a76..8667857107e4f2481fd98032d4333b08
  else:
    GN = 'gn'
  
-diff --git a/tools/generate_gn_filenames_json.py b/tools/generate_gn_filenames_json.py
-new file mode 100755
-index 0000000000000000000000000000000000000000..54b761d91734aead50aeeba8c91a1262531df713
---- /dev/null
-+++ b/tools/generate_gn_filenames_json.py
-@@ -0,0 +1,118 @@
-+#!/usr/bin/env python3
-+import json
-+import os
-+import sys
-+
-+import install
-+
-+from utils import SearchFiles
-+
-+def LoadPythonDictionary(path):
-+  file_string = open(path).read()
-+  try:
-+    file_data = eval(file_string, {'__builtins__': None}, None)
-+  except SyntaxError as e:
-+    e.filename = path
-+    raise
-+  except Exception as e:
-+    raise Exception("Unexpected error while reading %s: %s" % (path, str(e)))
-+
-+  assert isinstance(file_data, dict), "%s does not eval to a dictionary" % path
-+
-+  return file_data
-+
-+
-+FILENAMES_JSON_HEADER = '''
-+// This file is automatically generated by generate_gn_filenames_json.py
-+// DO NOT EDIT
-+'''.lstrip()
-+
-+SRC_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', '..'))
-+
-+def get_out_dir():
-+  out_dir = 'Testing'
-+  override = os.environ.get('ELECTRON_OUT_DIR')
-+  if override is not None:
-+    out_dir = override
-+  return os.path.join(SRC_DIR, 'out', out_dir)
-+
-+if __name__ == '__main__':
-+  node_root_dir = os.path.dirname(os.path.dirname(__file__))
-+  node_gyp_path = os.path.join(node_root_dir, 'node.gyp')
-+  out = {}
-+  node_gyp = LoadPythonDictionary(node_gyp_path)
-+  node_lib_target = next(
-+      t for t in node_gyp['targets']
-+      if t['target_name'] == '<(node_lib_target_name)')
-+  node_source_blocklist = {
-+      '<@(library_files)',
-+      '<@(deps_files)',
-+      '<@(node_sources)',
-+      'common.gypi',
-+      'common_node.gypi',
-+      '<(SHARED_INTERMEDIATE_DIR)/node_javascript.cc',
-+  }
-+
-+  def filter_v8_files(files):
-+    v8_files = [f for f in files if f.startswith('deps/v8/')]
-+    other_files = [f for f in files if not f.startswith('deps/v8/')]
-+
-+    for i, f in enumerate(v8_files):
-+        if not f.startswith('deps/v8/tools'):
-+            if f.endswith('js'):
-+                v8_files[i] = f.replace('deps/v8/', '../../v8/', 1)
-+            else:
-+                v8_files[i] = f.replace('deps/v8/', '//v8/')
-+
-+    if any(f == '<@(node_builtin_shareable_builtins)' for f in other_files):
-+      other_files.remove('<@(node_builtin_shareable_builtins)')
-+      shared_builtins = ['deps/cjs-module-lexer/lexer.js', 'deps/cjs-module-lexer/dist/lexer.js', 'deps/undici/undici.js']
-+      other_files.extend(shared_builtins)
-+
-+    return v8_files + other_files
-+
-+  def filter_fs_files(files):
-+    return [f for f in files if f.startswith('lib/internal/fs/')] + ['lib/fs.js'] + ['lib/fs/promises.js']
-+
-+  lib_files = SearchFiles('lib', 'js')
-+  out['library_files'] = filter_v8_files(lib_files)
-+  out['library_files'] += filter_v8_files(node_gyp['variables']['deps_files'])
-+  out['node_sources'] = node_gyp['variables']['node_sources']
-+
-+  out['fs_files'] = filter_fs_files(out['library_files'])
-+  # fs files are handled separately
-+  out['library_files'] = [f for f in out['library_files'] if f not in out['fs_files']]
-+
-+  blocklisted_sources = [
-+      f for f in node_lib_target['sources']
-+      if f not in node_source_blocklist]
-+  out['node_sources'] += filter_v8_files(blocklisted_sources)
-+
-+  out['headers'] = []
-+  def add_headers(options, files, dest_dir):
-+    if 'src/node.h' in files:
-+      files = [f for f in files if f.endswith('.h') and f != 'src/node_version.h']
-+    elif any(f.startswith('../../v8/') for f in files):
-+      files = [f.replace('../../v8/', '//v8/', 1) for f in files]
-+    if files:
-+      dir_index = next((i for i, d in enumerate(out['headers']) if d['dest_dir'] == dest_dir), -1)
-+      if (dir_index != -1):
-+        out['headers'][dir_index]['files'] += sorted(files)
-+      else:
-+        hs = {'files': sorted(files), 'dest_dir': dest_dir}
-+        out['headers'].append(hs)
-+
-+  config_gypi_path = os.path.join(get_out_dir(), 'gen', 'config.gypi')
-+  root_gen_dir = os.path.join(node_root_dir, 'out', 'Release', 'gen')
-+
-+  options = install.parse_options(['install', '--v8-dir', '../../v8', '--config-gypi-path', config_gypi_path, '--headers-only'])
-+  options.variables['node_use_openssl'] = 'false'
-+  options.variables['node_shared_libuv'] = 'false'
-+  # We generate zlib headers in Electron's BUILD.gn.
-+  options.variables['node_shared_zlib'] = ''
-+
-+  install.headers(options, add_headers)
-+  with open(os.path.join(node_root_dir, 'filenames.json'), 'w') as f:
-+    f.write(FILENAMES_JSON_HEADER)
-+    f.write(json.dumps(out, sort_keys=True, indent=2, separators=(',', ': ')))
-+    f.write('\n')
 diff --git a/tools/install.py b/tools/install.py
-index bf54249b66c0d4e179deaae5a9fd55568e694fe0..57b51b03d237fba4b25aa69a663c88e9541b6cb5 100755
+index bf54249b66c0d4e179deaae5a9fd55568e694fe0..31b94d2e4b532d3b8202b512e2d2f41d29a2a546 100755
 --- a/tools/install.py
 +++ b/tools/install.py
-@@ -392,7 +392,7 @@ def parse_options(args):
-   parser.add_argument('--build-dir', help='the location of built binaries',
-                       default='out/Release')
-   parser.add_argument('--v8-dir', help='the location of V8',
--                      default='deps/v8')
-+                      default='../../v8')
-   parser.add_argument('--config-gypi-path', help='the location of config.gypi',
-                       default='config.gypi')
-   parser.add_argument('--is-win', help='build for Windows target',
+@@ -285,6 +285,7 @@ def headers(options, action):
+       'include/v8-promise.h',
+       'include/v8-proxy.h',
+       'include/v8-regexp.h',
++      'include/v8-sandbox.h',
+       'include/v8-script.h',
+       'include/v8-snapshot.h',
+       'include/v8-source-location.h',
 diff --git a/tools/js2c.cc b/tools/js2c.cc
 old mode 100644
 new mode 100755

+ 0 - 13
patches/node/build_enable_perfetto.patch

@@ -12,19 +12,6 @@ adding associated guards there should be relatively small.
 
 We should upstream this as it will eventually impact Node.js as well.
 
-diff --git a/filenames.json b/filenames.json
-index 5af3886d8d3d74d31249a4d79030a8373b8dad52..8ab04d0b1b58454c6ea21f33870f9557f3a57b56 100644
---- a/filenames.json
-+++ b/filenames.json
-@@ -739,8 +739,6 @@
-     "src/tcp_wrap.h",
-     "src/timers.h",
-     "src/tracing/agent.h",
--    "src/tracing/node_trace_buffer.h",
--    "src/tracing/node_trace_writer.h",
-     "src/tracing/trace_event.h",
-     "src/tracing/trace_event_common.h",
-     "src/tracing/traced_value.h",
 diff --git a/lib/internal/constants.js b/lib/internal/constants.js
 index 8d7204f6cb48f783adc4d1c1eb2de0c83b7fffe2..a154559a56bf383d3c26af523c9bb07b564ef600 100644
 --- a/lib/internal/constants.js

+ 17 - 4
patches/node/fix_handle_boringssl_and_openssl_incompatibilities.patch

@@ -92,15 +92,28 @@ index eb3533bb4623b152605c3c590f37f086cce5f073..ded231aeaa15af22845704cfcc7d24a4
    }
    return CheckPublicKeyResult::NONE;
 diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h
-index 661c996889d0a89c1c38658a0933fcf5e3cdc1b9..1261d5d99fdf4e17b8dec66660028ce184f1cf89 100644
+index 60bfce3ea8999e8e145aaf8cd14f0fdf21ed9c54..55aae783bb57273d1b49927f65b6c0830d09d115 100644
 --- a/deps/ncrypto/ncrypto.h
 +++ b/deps/ncrypto/ncrypto.h
-@@ -413,8 +413,8 @@ public:
-   #ifndef OPENSSL_IS_BORINGSSL
+@@ -400,17 +400,21 @@ public:
+     UNABLE_TO_CHECK_GENERATOR = DH_UNABLE_TO_CHECK_GENERATOR,
+     NOT_SUITABLE_GENERATOR = DH_NOT_SUITABLE_GENERATOR,
+     Q_NOT_PRIME = DH_CHECK_Q_NOT_PRIME,
++#ifndef OPENSSL_IS_BORINGSSL
+     INVALID_Q = DH_CHECK_INVALID_Q_VALUE,
+     INVALID_J = DH_CHECK_INVALID_J_VALUE,
++#endif
+     CHECK_FAILED = 512,
+   };
+   CheckResult check();
+ 
+   enum class CheckPublicKeyResult {
+     NONE,
++#ifndef OPENSSL_IS_BORINGSSL
      TOO_SMALL = DH_R_CHECK_PUBKEY_TOO_SMALL,
      TOO_LARGE = DH_R_CHECK_PUBKEY_TOO_LARGE,
 -    INVALID = DH_R_CHECK_PUBKEY_INVALID,
-   #endif
++#endif
 +    INVALID = DH_R_INVALID_PUBKEY,
      CHECK_FAILED = 512,
    };

+ 107 - 0
script/node/generate_node_headers.py

@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+import json
+import os
+import sys
+import shutil
+
+from pathlib import Path
+
+SRC_DIR = Path(__file__).resolve().parents[3]
+sys.path.append(os.path.join(SRC_DIR, 'third_party/electron_node/tools'))
+
+import install
+
+class LoadPythonDictionaryError(Exception):
+    """Custom exception for errors in LoadPythonDictionary."""
+
+def LoadPythonDictionary(path):
+    with open(path, 'r', encoding='utf-8') as f:
+        file_string = f.read()
+        try:
+            file_data = eval(file_string, {'__builtins__': None}, None)
+        except SyntaxError as e:
+            e.filename = path
+            raise
+        except Exception as e:
+            err_msg = f"Unexpected error while reading {path}: {str(e)}"
+            raise LoadPythonDictionaryError(err_msg) from e
+        if not isinstance(file_data, dict):
+            raise LoadPythonDictionaryError(
+                f"{path} does not eval to a dictionary"
+            )
+        return file_data
+
+def get_out_dir():
+    out_dir = 'Testing'
+    override = os.environ.get('ELECTRON_OUT_DIR')
+    if override is not None:
+        out_dir = override
+    return os.path.join(SRC_DIR, 'out', out_dir)
+
+if __name__ == '__main__':
+    node_root_dir = os.path.join(SRC_DIR, 'third_party/electron_node')
+    out = {}
+
+    out['headers'] = []
+    def add_headers(_, files, dest_dir):
+        if 'src/node.h' in files:
+            files = [
+                f for f in files
+                if f.endswith('.h') and f != 'src/node_version.h'
+            ]
+        if files:
+            dir_index = next(
+                (i for i, d in enumerate(out['headers'])
+                if d['dest_dir'] == dest_dir),
+                -1
+            )
+            if dir_index != -1:
+                out['headers'][dir_index]['files'] += sorted(files)
+            else:
+                hs = {'files': sorted(files), 'dest_dir': dest_dir}
+                out['headers'].append(hs)
+
+    root_gen_dir = os.path.join(get_out_dir(), 'gen')
+    config_gypi_path = os.path.join(root_gen_dir, 'config.gypi')
+    node_headers_dir = os.path.join(root_gen_dir, 'node_headers')
+
+    options = install.parse_options([
+        'install',
+        '--root-dir', node_root_dir,
+        '--v8-dir', os.path.join(SRC_DIR, 'v8'),
+        '--config-gypi-path', config_gypi_path,
+        '--headers-only'
+    ])
+    options.variables['node_use_openssl'] = 'false'
+    options.variables['node_shared_libuv'] = 'false'
+    # We generate zlib headers in Electron's BUILD.gn.
+    options.variables['node_shared_zlib'] = ''
+    install.headers(options, add_headers)
+
+    header_groups = []
+    for header_group in out['headers']:
+        sources = [
+            os.path.join(node_root_dir, file)
+            for file in header_group['files']
+        ]
+        outputs = [
+            os.path.join(
+                node_headers_dir, header_group['dest_dir'],
+                os.path.basename(file)
+            )
+            for file in sources
+        ]
+        for src, dest in zip(sources, outputs):
+            os.makedirs(os.path.dirname(dest), exist_ok=True)
+            if os.path.exists(dest):
+                if os.path.samefile(src, dest):
+                    continue
+                os.remove(dest)
+            shutil.copyfile(src, dest)
+
+    node_header_file = os.path.join(root_gen_dir, 'node_headers.json')
+    with open(node_header_file, 'w', encoding='utf-8') as nhf:
+        json_data = json.dumps(
+            out, sort_keys=True, indent=2, separators=(',', ': ')
+        )
+        nhf.write(json_data)