perf: make better use of macros in generated defs.bzl files (#2157)

diff --git a/.bazelrc b/.bazelrc
index 2766b00..0498dd0 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -8,8 +8,6 @@
 
 ### YOUR PROJECT SPECIFIC OPTIONS GO HERE ###
 
-common --repo_env=CACHE_BUSTER="04/05/2025"
-
 # We have some empty globs in rules_js
 common --noincompatible_disallow_empty_glob
 
diff --git a/e2e/gyp_no_install_script/snapshots/bzlmod/segfault-handler_defs.bzl b/e2e/gyp_no_install_script/snapshots/bzlmod/segfault-handler_defs.bzl
index 25c7552..ad0d61c 100644
--- a/e2e/gyp_no_install_script/snapshots/bzlmod/segfault-handler_defs.bzl
+++ b/e2e/gyp_no_install_script/snapshots/bzlmod/segfault-handler_defs.bzl
@@ -4,370 +4,258 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
-load("@aspect_rules_js//js:defs.bzl", _js_run_binary = "js_run_binary")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
 
-# buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_package_internal.bzl", _npm_package_internal = "npm_package_internal")
+PACKAGE = "segfault-handler"
+VERSION = "1.3.0"
+_ROOT_PACKAGE = ""
+_PACKAGE_STORE_NAME = "segfault-handler@1.3.0"
 
 # Generated npm_package_store targets for npm package segfault-handler@1.3.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = ""
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package segfault-handler@1.3.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/@gar+promisify@1.1.3/pkg".format(link_root_name): "@gar/promisify",
-        ":.aspect_rules_js/{}/@npmcli+fs@2.1.2/pkg".format(link_root_name): "@npmcli/fs",
-        ":.aspect_rules_js/{}/@npmcli+move-file@2.0.1/pkg".format(link_root_name): "@npmcli/move-file",
-        ":.aspect_rules_js/{}/@tootallnate+once@2.0.0/pkg".format(link_root_name): "@tootallnate/once",
-        ":.aspect_rules_js/{}/abbrev@1.1.1/pkg".format(link_root_name): "abbrev",
-        ":.aspect_rules_js/{}/agent-base@6.0.2/pkg".format(link_root_name): "agent-base",
-        ":.aspect_rules_js/{}/agentkeepalive@4.2.1/pkg".format(link_root_name): "agentkeepalive",
-        ":.aspect_rules_js/{}/aggregate-error@3.1.0/pkg".format(link_root_name): "aggregate-error",
-        ":.aspect_rules_js/{}/ansi-regex@5.0.1/pkg".format(link_root_name): "ansi-regex",
-        ":.aspect_rules_js/{}/aproba@2.0.0/pkg".format(link_root_name): "aproba",
-        ":.aspect_rules_js/{}/are-we-there-yet@3.0.1/pkg".format(link_root_name): "are-we-there-yet",
-        ":.aspect_rules_js/{}/balanced-match@1.0.2/pkg".format(link_root_name): "balanced-match",
-        ":.aspect_rules_js/{}/bindings@1.5.0/pkg".format(link_root_name): "bindings",
-        ":.aspect_rules_js/{}/brace-expansion@1.1.11/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/brace-expansion@2.0.1/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/cacache@16.1.3/pkg".format(link_root_name): "cacache",
-        ":.aspect_rules_js/{}/chownr@2.0.0/pkg".format(link_root_name): "chownr",
-        ":.aspect_rules_js/{}/clean-stack@2.2.0/pkg".format(link_root_name): "clean-stack",
-        ":.aspect_rules_js/{}/color-support@1.1.3/pkg".format(link_root_name): "color-support",
-        ":.aspect_rules_js/{}/concat-map@0.0.1/pkg".format(link_root_name): "concat-map",
-        ":.aspect_rules_js/{}/console-control-strings@1.1.0/pkg".format(link_root_name): "console-control-strings",
-        ":.aspect_rules_js/{}/debug@4.3.4/pkg".format(link_root_name): "debug",
-        ":.aspect_rules_js/{}/delegates@1.0.0/pkg".format(link_root_name): "delegates",
-        ":.aspect_rules_js/{}/depd@1.1.2/pkg".format(link_root_name): "depd",
-        ":.aspect_rules_js/{}/emoji-regex@8.0.0/pkg".format(link_root_name): "emoji-regex",
-        ":.aspect_rules_js/{}/encoding@0.1.13/pkg".format(link_root_name): "encoding",
-        ":.aspect_rules_js/{}/env-paths@2.2.1/pkg".format(link_root_name): "env-paths",
-        ":.aspect_rules_js/{}/err-code@2.0.3/pkg".format(link_root_name): "err-code",
-        ":.aspect_rules_js/{}/file-uri-to-path@1.0.0/pkg".format(link_root_name): "file-uri-to-path",
-        ":.aspect_rules_js/{}/fs-minipass@2.1.0/pkg".format(link_root_name): "fs-minipass",
-        ":.aspect_rules_js/{}/fs.realpath@1.0.0/pkg".format(link_root_name): "fs.realpath",
-        ":.aspect_rules_js/{}/gauge@4.0.4/pkg".format(link_root_name): "gauge",
-        ":.aspect_rules_js/{}/glob@7.2.3/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/glob@8.1.0/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/graceful-fs@4.2.10/pkg".format(link_root_name): "graceful-fs",
-        ":.aspect_rules_js/{}/has-unicode@2.0.1/pkg".format(link_root_name): "has-unicode",
-        ":.aspect_rules_js/{}/http-cache-semantics@4.1.1/pkg".format(link_root_name): "http-cache-semantics",
-        ":.aspect_rules_js/{}/http-proxy-agent@5.0.0/pkg".format(link_root_name): "http-proxy-agent",
-        ":.aspect_rules_js/{}/https-proxy-agent@5.0.1/pkg".format(link_root_name): "https-proxy-agent",
-        ":.aspect_rules_js/{}/humanize-ms@1.2.1/pkg".format(link_root_name): "humanize-ms",
-        ":.aspect_rules_js/{}/iconv-lite@0.6.3/pkg".format(link_root_name): "iconv-lite",
-        ":.aspect_rules_js/{}/imurmurhash@0.1.4/pkg".format(link_root_name): "imurmurhash",
-        ":.aspect_rules_js/{}/indent-string@4.0.0/pkg".format(link_root_name): "indent-string",
-        ":.aspect_rules_js/{}/infer-owner@1.0.4/pkg".format(link_root_name): "infer-owner",
-        ":.aspect_rules_js/{}/inflight@1.0.6/pkg".format(link_root_name): "inflight",
-        ":.aspect_rules_js/{}/inherits@2.0.4/pkg".format(link_root_name): "inherits",
-        ":.aspect_rules_js/{}/ip@2.0.0/pkg".format(link_root_name): "ip",
-        ":.aspect_rules_js/{}/is-fullwidth-code-point@3.0.0/pkg".format(link_root_name): "is-fullwidth-code-point",
-        ":.aspect_rules_js/{}/is-lambda@1.0.1/pkg".format(link_root_name): "is-lambda",
-        ":.aspect_rules_js/{}/isexe@2.0.0/pkg".format(link_root_name): "isexe",
-        ":.aspect_rules_js/{}/lru-cache@6.0.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/lru-cache@7.17.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/make-fetch-happen@10.2.1/pkg".format(link_root_name): "make-fetch-happen",
-        ":.aspect_rules_js/{}/minimatch@3.1.2/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minimatch@5.1.6/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minipass@3.3.6/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass@4.2.4/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass-collect@1.0.2/pkg".format(link_root_name): "minipass-collect",
-        ":.aspect_rules_js/{}/minipass-fetch@2.1.2/pkg".format(link_root_name): "minipass-fetch",
-        ":.aspect_rules_js/{}/minipass-flush@1.0.5/pkg".format(link_root_name): "minipass-flush",
-        ":.aspect_rules_js/{}/minipass-pipeline@1.2.4/pkg".format(link_root_name): "minipass-pipeline",
-        ":.aspect_rules_js/{}/minipass-sized@1.0.3/pkg".format(link_root_name): "minipass-sized",
-        ":.aspect_rules_js/{}/minizlib@2.1.2/pkg".format(link_root_name): "minizlib",
-        ":.aspect_rules_js/{}/mkdirp@1.0.4/pkg".format(link_root_name): "mkdirp",
-        ":.aspect_rules_js/{}/ms@2.1.3/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/ms@2.1.2/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/nan@2.17.0/pkg".format(link_root_name): "nan",
-        ":.aspect_rules_js/{}/negotiator@0.6.3/pkg".format(link_root_name): "negotiator",
-        ":.aspect_rules_js/{}/node-gyp@9.3.1/pkg".format(link_root_name): "node-gyp",
-        ":.aspect_rules_js/{}/nopt@6.0.0/pkg".format(link_root_name): "nopt",
-        ":.aspect_rules_js/{}/npmlog@6.0.2/pkg".format(link_root_name): "npmlog",
-        ":.aspect_rules_js/{}/once@1.4.0/pkg".format(link_root_name): "once",
-        ":.aspect_rules_js/{}/p-map@4.0.0/pkg".format(link_root_name): "p-map",
-        ":.aspect_rules_js/{}/path-is-absolute@1.0.1/pkg".format(link_root_name): "path-is-absolute",
-        ":.aspect_rules_js/{}/promise-inflight@1.0.1/pkg".format(link_root_name): "promise-inflight",
-        ":.aspect_rules_js/{}/promise-retry@2.0.1/pkg".format(link_root_name): "promise-retry",
-        ":.aspect_rules_js/{}/readable-stream@3.6.1/pkg".format(link_root_name): "readable-stream",
-        ":.aspect_rules_js/{}/retry@0.12.0/pkg".format(link_root_name): "retry",
-        ":.aspect_rules_js/{}/rimraf@3.0.2/pkg".format(link_root_name): "rimraf",
-        ":.aspect_rules_js/{}/safe-buffer@5.2.1/pkg".format(link_root_name): "safe-buffer",
-        ":.aspect_rules_js/{}/safer-buffer@2.1.2/pkg".format(link_root_name): "safer-buffer",
-        ":.aspect_rules_js/{}/segfault-handler@1.3.0/pkg".format(link_root_name): "segfault-handler",
-        ":.aspect_rules_js/{}/semver@7.3.8/pkg".format(link_root_name): "semver",
-        ":.aspect_rules_js/{}/set-blocking@2.0.0/pkg".format(link_root_name): "set-blocking",
-        ":.aspect_rules_js/{}/signal-exit@3.0.7/pkg".format(link_root_name): "signal-exit",
-        ":.aspect_rules_js/{}/smart-buffer@4.2.0/pkg".format(link_root_name): "smart-buffer",
-        ":.aspect_rules_js/{}/socks@2.7.1/pkg".format(link_root_name): "socks",
-        ":.aspect_rules_js/{}/socks-proxy-agent@7.0.0/pkg".format(link_root_name): "socks-proxy-agent",
-        ":.aspect_rules_js/{}/ssri@9.0.1/pkg".format(link_root_name): "ssri",
-        ":.aspect_rules_js/{}/string-width@4.2.3/pkg".format(link_root_name): "string-width",
-        ":.aspect_rules_js/{}/string_decoder@1.3.0/pkg".format(link_root_name): "string_decoder",
-        ":.aspect_rules_js/{}/strip-ansi@6.0.1/pkg".format(link_root_name): "strip-ansi",
-        ":.aspect_rules_js/{}/tar@6.1.13/pkg".format(link_root_name): "tar",
-        ":.aspect_rules_js/{}/unique-filename@2.0.1/pkg".format(link_root_name): "unique-filename",
-        ":.aspect_rules_js/{}/unique-slug@3.0.0/pkg".format(link_root_name): "unique-slug",
-        ":.aspect_rules_js/{}/util-deprecate@1.0.2/pkg".format(link_root_name): "util-deprecate",
-        ":.aspect_rules_js/{}/which@2.0.2/pkg".format(link_root_name): "which",
-        ":.aspect_rules_js/{}/wide-align@1.1.5/pkg".format(link_root_name): "wide-align",
-        ":.aspect_rules_js/{}/wrappy@1.0.2/pkg".format(link_root_name): "wrappy",
-        ":.aspect_rules_js/{}/yallist@4.0.0/pkg".format(link_root_name): "yallist",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/bindings@1.5.0/ref".format(link_root_name): "bindings",
-        ":.aspect_rules_js/{}/nan@2.17.0/ref".format(link_root_name): "nan",
-        ":.aspect_rules_js/{}/node-gyp@9.3.1/ref".format(link_root_name): "node-gyp",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/segfault-handler@1.3.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/@gar+promisify@1.1.3/pkg": "@gar/promisify",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+fs@2.1.2/pkg": "@npmcli/fs",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+move-file@2.0.1/pkg": "@npmcli/move-file",
+            ":.aspect_rules_js/{link_root_name}/@tootallnate+once@2.0.0/pkg": "@tootallnate/once",
+            ":.aspect_rules_js/{link_root_name}/abbrev@1.1.1/pkg": "abbrev",
+            ":.aspect_rules_js/{link_root_name}/agent-base@6.0.2/pkg": "agent-base",
+            ":.aspect_rules_js/{link_root_name}/agentkeepalive@4.2.1/pkg": "agentkeepalive",
+            ":.aspect_rules_js/{link_root_name}/aggregate-error@3.1.0/pkg": "aggregate-error",
+            ":.aspect_rules_js/{link_root_name}/ansi-regex@5.0.1/pkg": "ansi-regex",
+            ":.aspect_rules_js/{link_root_name}/aproba@2.0.0/pkg": "aproba",
+            ":.aspect_rules_js/{link_root_name}/are-we-there-yet@3.0.1/pkg": "are-we-there-yet",
+            ":.aspect_rules_js/{link_root_name}/balanced-match@1.0.2/pkg": "balanced-match",
+            ":.aspect_rules_js/{link_root_name}/bindings@1.5.0/pkg": "bindings",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@1.1.11/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@2.0.1/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/cacache@16.1.3/pkg": "cacache",
+            ":.aspect_rules_js/{link_root_name}/chownr@2.0.0/pkg": "chownr",
+            ":.aspect_rules_js/{link_root_name}/clean-stack@2.2.0/pkg": "clean-stack",
+            ":.aspect_rules_js/{link_root_name}/color-support@1.1.3/pkg": "color-support",
+            ":.aspect_rules_js/{link_root_name}/concat-map@0.0.1/pkg": "concat-map",
+            ":.aspect_rules_js/{link_root_name}/console-control-strings@1.1.0/pkg": "console-control-strings",
+            ":.aspect_rules_js/{link_root_name}/debug@4.3.4/pkg": "debug",
+            ":.aspect_rules_js/{link_root_name}/delegates@1.0.0/pkg": "delegates",
+            ":.aspect_rules_js/{link_root_name}/depd@1.1.2/pkg": "depd",
+            ":.aspect_rules_js/{link_root_name}/emoji-regex@8.0.0/pkg": "emoji-regex",
+            ":.aspect_rules_js/{link_root_name}/encoding@0.1.13/pkg": "encoding",
+            ":.aspect_rules_js/{link_root_name}/env-paths@2.2.1/pkg": "env-paths",
+            ":.aspect_rules_js/{link_root_name}/err-code@2.0.3/pkg": "err-code",
+            ":.aspect_rules_js/{link_root_name}/file-uri-to-path@1.0.0/pkg": "file-uri-to-path",
+            ":.aspect_rules_js/{link_root_name}/fs-minipass@2.1.0/pkg": "fs-minipass",
+            ":.aspect_rules_js/{link_root_name}/fs.realpath@1.0.0/pkg": "fs.realpath",
+            ":.aspect_rules_js/{link_root_name}/gauge@4.0.4/pkg": "gauge",
+            ":.aspect_rules_js/{link_root_name}/glob@7.2.3/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/glob@8.1.0/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/graceful-fs@4.2.10/pkg": "graceful-fs",
+            ":.aspect_rules_js/{link_root_name}/has-unicode@2.0.1/pkg": "has-unicode",
+            ":.aspect_rules_js/{link_root_name}/http-cache-semantics@4.1.1/pkg": "http-cache-semantics",
+            ":.aspect_rules_js/{link_root_name}/http-proxy-agent@5.0.0/pkg": "http-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/https-proxy-agent@5.0.1/pkg": "https-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/humanize-ms@1.2.1/pkg": "humanize-ms",
+            ":.aspect_rules_js/{link_root_name}/iconv-lite@0.6.3/pkg": "iconv-lite",
+            ":.aspect_rules_js/{link_root_name}/imurmurhash@0.1.4/pkg": "imurmurhash",
+            ":.aspect_rules_js/{link_root_name}/indent-string@4.0.0/pkg": "indent-string",
+            ":.aspect_rules_js/{link_root_name}/infer-owner@1.0.4/pkg": "infer-owner",
+            ":.aspect_rules_js/{link_root_name}/inflight@1.0.6/pkg": "inflight",
+            ":.aspect_rules_js/{link_root_name}/inherits@2.0.4/pkg": "inherits",
+            ":.aspect_rules_js/{link_root_name}/ip@2.0.0/pkg": "ip",
+            ":.aspect_rules_js/{link_root_name}/is-fullwidth-code-point@3.0.0/pkg": "is-fullwidth-code-point",
+            ":.aspect_rules_js/{link_root_name}/is-lambda@1.0.1/pkg": "is-lambda",
+            ":.aspect_rules_js/{link_root_name}/isexe@2.0.0/pkg": "isexe",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@6.0.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@7.17.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/make-fetch-happen@10.2.1/pkg": "make-fetch-happen",
+            ":.aspect_rules_js/{link_root_name}/minimatch@3.1.2/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minimatch@5.1.6/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minipass@3.3.6/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass@4.2.4/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass-collect@1.0.2/pkg": "minipass-collect",
+            ":.aspect_rules_js/{link_root_name}/minipass-fetch@2.1.2/pkg": "minipass-fetch",
+            ":.aspect_rules_js/{link_root_name}/minipass-flush@1.0.5/pkg": "minipass-flush",
+            ":.aspect_rules_js/{link_root_name}/minipass-pipeline@1.2.4/pkg": "minipass-pipeline",
+            ":.aspect_rules_js/{link_root_name}/minipass-sized@1.0.3/pkg": "minipass-sized",
+            ":.aspect_rules_js/{link_root_name}/minizlib@2.1.2/pkg": "minizlib",
+            ":.aspect_rules_js/{link_root_name}/mkdirp@1.0.4/pkg": "mkdirp",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.3/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.2/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/nan@2.17.0/pkg": "nan",
+            ":.aspect_rules_js/{link_root_name}/negotiator@0.6.3/pkg": "negotiator",
+            ":.aspect_rules_js/{link_root_name}/node-gyp@9.3.1/pkg": "node-gyp",
+            ":.aspect_rules_js/{link_root_name}/nopt@6.0.0/pkg": "nopt",
+            ":.aspect_rules_js/{link_root_name}/npmlog@6.0.2/pkg": "npmlog",
+            ":.aspect_rules_js/{link_root_name}/once@1.4.0/pkg": "once",
+            ":.aspect_rules_js/{link_root_name}/p-map@4.0.0/pkg": "p-map",
+            ":.aspect_rules_js/{link_root_name}/path-is-absolute@1.0.1/pkg": "path-is-absolute",
+            ":.aspect_rules_js/{link_root_name}/promise-inflight@1.0.1/pkg": "promise-inflight",
+            ":.aspect_rules_js/{link_root_name}/promise-retry@2.0.1/pkg": "promise-retry",
+            ":.aspect_rules_js/{link_root_name}/readable-stream@3.6.1/pkg": "readable-stream",
+            ":.aspect_rules_js/{link_root_name}/retry@0.12.0/pkg": "retry",
+            ":.aspect_rules_js/{link_root_name}/rimraf@3.0.2/pkg": "rimraf",
+            ":.aspect_rules_js/{link_root_name}/safe-buffer@5.2.1/pkg": "safe-buffer",
+            ":.aspect_rules_js/{link_root_name}/safer-buffer@2.1.2/pkg": "safer-buffer",
+            ":.aspect_rules_js/{link_root_name}/segfault-handler@1.3.0/pkg": "segfault-handler",
+            ":.aspect_rules_js/{link_root_name}/semver@7.3.8/pkg": "semver",
+            ":.aspect_rules_js/{link_root_name}/set-blocking@2.0.0/pkg": "set-blocking",
+            ":.aspect_rules_js/{link_root_name}/signal-exit@3.0.7/pkg": "signal-exit",
+            ":.aspect_rules_js/{link_root_name}/smart-buffer@4.2.0/pkg": "smart-buffer",
+            ":.aspect_rules_js/{link_root_name}/socks@2.7.1/pkg": "socks",
+            ":.aspect_rules_js/{link_root_name}/socks-proxy-agent@7.0.0/pkg": "socks-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/ssri@9.0.1/pkg": "ssri",
+            ":.aspect_rules_js/{link_root_name}/string-width@4.2.3/pkg": "string-width",
+            ":.aspect_rules_js/{link_root_name}/string_decoder@1.3.0/pkg": "string_decoder",
+            ":.aspect_rules_js/{link_root_name}/strip-ansi@6.0.1/pkg": "strip-ansi",
+            ":.aspect_rules_js/{link_root_name}/tar@6.1.13/pkg": "tar",
+            ":.aspect_rules_js/{link_root_name}/unique-filename@2.0.1/pkg": "unique-filename",
+            ":.aspect_rules_js/{link_root_name}/unique-slug@3.0.0/pkg": "unique-slug",
+            ":.aspect_rules_js/{link_root_name}/util-deprecate@1.0.2/pkg": "util-deprecate",
+            ":.aspect_rules_js/{link_root_name}/which@2.0.2/pkg": "which",
+            ":.aspect_rules_js/{link_root_name}/wide-align@1.1.5/pkg": "wide-align",
+            ":.aspect_rules_js/{link_root_name}/wrappy@1.0.2/pkg": "wrappy",
+            ":.aspect_rules_js/{link_root_name}/yallist@4.0.0/pkg": "yallist",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/bindings@1.5.0/ref": "bindings",
+            ":.aspect_rules_js/{link_root_name}/nan@2.17.0/ref": "nan",
+            ":.aspect_rules_js/{link_root_name}/node-gyp@9.3.1/ref": "node-gyp",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/@gar+promisify@1.1.3/pkg": "@gar/promisify",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+fs@2.1.2/pkg": "@npmcli/fs",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+move-file@2.0.1/pkg": "@npmcli/move-file",
+            ":.aspect_rules_js/{link_root_name}/@tootallnate+once@2.0.0/pkg": "@tootallnate/once",
+            ":.aspect_rules_js/{link_root_name}/abbrev@1.1.1/pkg": "abbrev",
+            ":.aspect_rules_js/{link_root_name}/agent-base@6.0.2/pkg": "agent-base",
+            ":.aspect_rules_js/{link_root_name}/agentkeepalive@4.2.1/pkg": "agentkeepalive",
+            ":.aspect_rules_js/{link_root_name}/aggregate-error@3.1.0/pkg": "aggregate-error",
+            ":.aspect_rules_js/{link_root_name}/ansi-regex@5.0.1/pkg": "ansi-regex",
+            ":.aspect_rules_js/{link_root_name}/aproba@2.0.0/pkg": "aproba",
+            ":.aspect_rules_js/{link_root_name}/are-we-there-yet@3.0.1/pkg": "are-we-there-yet",
+            ":.aspect_rules_js/{link_root_name}/balanced-match@1.0.2/pkg": "balanced-match",
+            ":.aspect_rules_js/{link_root_name}/bindings@1.5.0/pkg": "bindings",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@1.1.11/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@2.0.1/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/cacache@16.1.3/pkg": "cacache",
+            ":.aspect_rules_js/{link_root_name}/chownr@2.0.0/pkg": "chownr",
+            ":.aspect_rules_js/{link_root_name}/clean-stack@2.2.0/pkg": "clean-stack",
+            ":.aspect_rules_js/{link_root_name}/color-support@1.1.3/pkg": "color-support",
+            ":.aspect_rules_js/{link_root_name}/concat-map@0.0.1/pkg": "concat-map",
+            ":.aspect_rules_js/{link_root_name}/console-control-strings@1.1.0/pkg": "console-control-strings",
+            ":.aspect_rules_js/{link_root_name}/debug@4.3.4/pkg": "debug",
+            ":.aspect_rules_js/{link_root_name}/delegates@1.0.0/pkg": "delegates",
+            ":.aspect_rules_js/{link_root_name}/depd@1.1.2/pkg": "depd",
+            ":.aspect_rules_js/{link_root_name}/emoji-regex@8.0.0/pkg": "emoji-regex",
+            ":.aspect_rules_js/{link_root_name}/encoding@0.1.13/pkg": "encoding",
+            ":.aspect_rules_js/{link_root_name}/env-paths@2.2.1/pkg": "env-paths",
+            ":.aspect_rules_js/{link_root_name}/err-code@2.0.3/pkg": "err-code",
+            ":.aspect_rules_js/{link_root_name}/file-uri-to-path@1.0.0/pkg": "file-uri-to-path",
+            ":.aspect_rules_js/{link_root_name}/fs-minipass@2.1.0/pkg": "fs-minipass",
+            ":.aspect_rules_js/{link_root_name}/fs.realpath@1.0.0/pkg": "fs.realpath",
+            ":.aspect_rules_js/{link_root_name}/gauge@4.0.4/pkg": "gauge",
+            ":.aspect_rules_js/{link_root_name}/glob@7.2.3/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/glob@8.1.0/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/graceful-fs@4.2.10/pkg": "graceful-fs",
+            ":.aspect_rules_js/{link_root_name}/has-unicode@2.0.1/pkg": "has-unicode",
+            ":.aspect_rules_js/{link_root_name}/http-cache-semantics@4.1.1/pkg": "http-cache-semantics",
+            ":.aspect_rules_js/{link_root_name}/http-proxy-agent@5.0.0/pkg": "http-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/https-proxy-agent@5.0.1/pkg": "https-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/humanize-ms@1.2.1/pkg": "humanize-ms",
+            ":.aspect_rules_js/{link_root_name}/iconv-lite@0.6.3/pkg": "iconv-lite",
+            ":.aspect_rules_js/{link_root_name}/imurmurhash@0.1.4/pkg": "imurmurhash",
+            ":.aspect_rules_js/{link_root_name}/indent-string@4.0.0/pkg": "indent-string",
+            ":.aspect_rules_js/{link_root_name}/infer-owner@1.0.4/pkg": "infer-owner",
+            ":.aspect_rules_js/{link_root_name}/inflight@1.0.6/pkg": "inflight",
+            ":.aspect_rules_js/{link_root_name}/inherits@2.0.4/pkg": "inherits",
+            ":.aspect_rules_js/{link_root_name}/ip@2.0.0/pkg": "ip",
+            ":.aspect_rules_js/{link_root_name}/is-fullwidth-code-point@3.0.0/pkg": "is-fullwidth-code-point",
+            ":.aspect_rules_js/{link_root_name}/is-lambda@1.0.1/pkg": "is-lambda",
+            ":.aspect_rules_js/{link_root_name}/isexe@2.0.0/pkg": "isexe",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@6.0.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@7.17.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/make-fetch-happen@10.2.1/pkg": "make-fetch-happen",
+            ":.aspect_rules_js/{link_root_name}/minimatch@3.1.2/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minimatch@5.1.6/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minipass@3.3.6/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass@4.2.4/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass-collect@1.0.2/pkg": "minipass-collect",
+            ":.aspect_rules_js/{link_root_name}/minipass-fetch@2.1.2/pkg": "minipass-fetch",
+            ":.aspect_rules_js/{link_root_name}/minipass-flush@1.0.5/pkg": "minipass-flush",
+            ":.aspect_rules_js/{link_root_name}/minipass-pipeline@1.2.4/pkg": "minipass-pipeline",
+            ":.aspect_rules_js/{link_root_name}/minipass-sized@1.0.3/pkg": "minipass-sized",
+            ":.aspect_rules_js/{link_root_name}/minizlib@2.1.2/pkg": "minizlib",
+            ":.aspect_rules_js/{link_root_name}/mkdirp@1.0.4/pkg": "mkdirp",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.3/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.2/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/nan@2.17.0/pkg": "nan",
+            ":.aspect_rules_js/{link_root_name}/negotiator@0.6.3/pkg": "negotiator",
+            ":.aspect_rules_js/{link_root_name}/node-gyp@9.3.1/pkg": "node-gyp",
+            ":.aspect_rules_js/{link_root_name}/nopt@6.0.0/pkg": "nopt",
+            ":.aspect_rules_js/{link_root_name}/npmlog@6.0.2/pkg": "npmlog",
+            ":.aspect_rules_js/{link_root_name}/once@1.4.0/pkg": "once",
+            ":.aspect_rules_js/{link_root_name}/p-map@4.0.0/pkg": "p-map",
+            ":.aspect_rules_js/{link_root_name}/path-is-absolute@1.0.1/pkg": "path-is-absolute",
+            ":.aspect_rules_js/{link_root_name}/promise-inflight@1.0.1/pkg": "promise-inflight",
+            ":.aspect_rules_js/{link_root_name}/promise-retry@2.0.1/pkg": "promise-retry",
+            ":.aspect_rules_js/{link_root_name}/readable-stream@3.6.1/pkg": "readable-stream",
+            ":.aspect_rules_js/{link_root_name}/retry@0.12.0/pkg": "retry",
+            ":.aspect_rules_js/{link_root_name}/rimraf@3.0.2/pkg": "rimraf",
+            ":.aspect_rules_js/{link_root_name}/safe-buffer@5.2.1/pkg": "safe-buffer",
+            ":.aspect_rules_js/{link_root_name}/safer-buffer@2.1.2/pkg": "safer-buffer",
+            ":.aspect_rules_js/{link_root_name}/segfault-handler@1.3.0/pkg_pre_lc_lite": "segfault-handler",
+            ":.aspect_rules_js/{link_root_name}/semver@7.3.8/pkg": "semver",
+            ":.aspect_rules_js/{link_root_name}/set-blocking@2.0.0/pkg": "set-blocking",
+            ":.aspect_rules_js/{link_root_name}/signal-exit@3.0.7/pkg": "signal-exit",
+            ":.aspect_rules_js/{link_root_name}/smart-buffer@4.2.0/pkg": "smart-buffer",
+            ":.aspect_rules_js/{link_root_name}/socks@2.7.1/pkg": "socks",
+            ":.aspect_rules_js/{link_root_name}/socks-proxy-agent@7.0.0/pkg": "socks-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/ssri@9.0.1/pkg": "ssri",
+            ":.aspect_rules_js/{link_root_name}/string-width@4.2.3/pkg": "string-width",
+            ":.aspect_rules_js/{link_root_name}/string_decoder@1.3.0/pkg": "string_decoder",
+            ":.aspect_rules_js/{link_root_name}/strip-ansi@6.0.1/pkg": "strip-ansi",
+            ":.aspect_rules_js/{link_root_name}/tar@6.1.13/pkg": "tar",
+            ":.aspect_rules_js/{link_root_name}/unique-filename@2.0.1/pkg": "unique-filename",
+            ":.aspect_rules_js/{link_root_name}/unique-slug@3.0.0/pkg": "unique-slug",
+            ":.aspect_rules_js/{link_root_name}/util-deprecate@1.0.2/pkg": "util-deprecate",
+            ":.aspect_rules_js/{link_root_name}/which@2.0.2/pkg": "which",
+            ":.aspect_rules_js/{link_root_name}/wide-align@1.1.5/pkg": "wide-align",
+            ":.aspect_rules_js/{link_root_name}/wrappy@1.0.2/pkg": "wrappy",
+            ":.aspect_rules_js/{link_root_name}/yallist@4.0.0/pkg": "yallist",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if True else "@@aspect_rules_js~~npm~npm__segfault-handler__1.3.0//:pkg",
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@aspect_rules_js~~npm~npm__segfault-handler__1.3.0//:pkg",
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    lc_deps = {
-        ":.aspect_rules_js/{}/@gar+promisify@1.1.3/pkg".format(link_root_name): "@gar/promisify",
-        ":.aspect_rules_js/{}/@npmcli+fs@2.1.2/pkg".format(link_root_name): "@npmcli/fs",
-        ":.aspect_rules_js/{}/@npmcli+move-file@2.0.1/pkg".format(link_root_name): "@npmcli/move-file",
-        ":.aspect_rules_js/{}/@tootallnate+once@2.0.0/pkg".format(link_root_name): "@tootallnate/once",
-        ":.aspect_rules_js/{}/abbrev@1.1.1/pkg".format(link_root_name): "abbrev",
-        ":.aspect_rules_js/{}/agent-base@6.0.2/pkg".format(link_root_name): "agent-base",
-        ":.aspect_rules_js/{}/agentkeepalive@4.2.1/pkg".format(link_root_name): "agentkeepalive",
-        ":.aspect_rules_js/{}/aggregate-error@3.1.0/pkg".format(link_root_name): "aggregate-error",
-        ":.aspect_rules_js/{}/ansi-regex@5.0.1/pkg".format(link_root_name): "ansi-regex",
-        ":.aspect_rules_js/{}/aproba@2.0.0/pkg".format(link_root_name): "aproba",
-        ":.aspect_rules_js/{}/are-we-there-yet@3.0.1/pkg".format(link_root_name): "are-we-there-yet",
-        ":.aspect_rules_js/{}/balanced-match@1.0.2/pkg".format(link_root_name): "balanced-match",
-        ":.aspect_rules_js/{}/bindings@1.5.0/pkg".format(link_root_name): "bindings",
-        ":.aspect_rules_js/{}/brace-expansion@1.1.11/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/brace-expansion@2.0.1/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/cacache@16.1.3/pkg".format(link_root_name): "cacache",
-        ":.aspect_rules_js/{}/chownr@2.0.0/pkg".format(link_root_name): "chownr",
-        ":.aspect_rules_js/{}/clean-stack@2.2.0/pkg".format(link_root_name): "clean-stack",
-        ":.aspect_rules_js/{}/color-support@1.1.3/pkg".format(link_root_name): "color-support",
-        ":.aspect_rules_js/{}/concat-map@0.0.1/pkg".format(link_root_name): "concat-map",
-        ":.aspect_rules_js/{}/console-control-strings@1.1.0/pkg".format(link_root_name): "console-control-strings",
-        ":.aspect_rules_js/{}/debug@4.3.4/pkg".format(link_root_name): "debug",
-        ":.aspect_rules_js/{}/delegates@1.0.0/pkg".format(link_root_name): "delegates",
-        ":.aspect_rules_js/{}/depd@1.1.2/pkg".format(link_root_name): "depd",
-        ":.aspect_rules_js/{}/emoji-regex@8.0.0/pkg".format(link_root_name): "emoji-regex",
-        ":.aspect_rules_js/{}/encoding@0.1.13/pkg".format(link_root_name): "encoding",
-        ":.aspect_rules_js/{}/env-paths@2.2.1/pkg".format(link_root_name): "env-paths",
-        ":.aspect_rules_js/{}/err-code@2.0.3/pkg".format(link_root_name): "err-code",
-        ":.aspect_rules_js/{}/file-uri-to-path@1.0.0/pkg".format(link_root_name): "file-uri-to-path",
-        ":.aspect_rules_js/{}/fs-minipass@2.1.0/pkg".format(link_root_name): "fs-minipass",
-        ":.aspect_rules_js/{}/fs.realpath@1.0.0/pkg".format(link_root_name): "fs.realpath",
-        ":.aspect_rules_js/{}/gauge@4.0.4/pkg".format(link_root_name): "gauge",
-        ":.aspect_rules_js/{}/glob@7.2.3/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/glob@8.1.0/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/graceful-fs@4.2.10/pkg".format(link_root_name): "graceful-fs",
-        ":.aspect_rules_js/{}/has-unicode@2.0.1/pkg".format(link_root_name): "has-unicode",
-        ":.aspect_rules_js/{}/http-cache-semantics@4.1.1/pkg".format(link_root_name): "http-cache-semantics",
-        ":.aspect_rules_js/{}/http-proxy-agent@5.0.0/pkg".format(link_root_name): "http-proxy-agent",
-        ":.aspect_rules_js/{}/https-proxy-agent@5.0.1/pkg".format(link_root_name): "https-proxy-agent",
-        ":.aspect_rules_js/{}/humanize-ms@1.2.1/pkg".format(link_root_name): "humanize-ms",
-        ":.aspect_rules_js/{}/iconv-lite@0.6.3/pkg".format(link_root_name): "iconv-lite",
-        ":.aspect_rules_js/{}/imurmurhash@0.1.4/pkg".format(link_root_name): "imurmurhash",
-        ":.aspect_rules_js/{}/indent-string@4.0.0/pkg".format(link_root_name): "indent-string",
-        ":.aspect_rules_js/{}/infer-owner@1.0.4/pkg".format(link_root_name): "infer-owner",
-        ":.aspect_rules_js/{}/inflight@1.0.6/pkg".format(link_root_name): "inflight",
-        ":.aspect_rules_js/{}/inherits@2.0.4/pkg".format(link_root_name): "inherits",
-        ":.aspect_rules_js/{}/ip@2.0.0/pkg".format(link_root_name): "ip",
-        ":.aspect_rules_js/{}/is-fullwidth-code-point@3.0.0/pkg".format(link_root_name): "is-fullwidth-code-point",
-        ":.aspect_rules_js/{}/is-lambda@1.0.1/pkg".format(link_root_name): "is-lambda",
-        ":.aspect_rules_js/{}/isexe@2.0.0/pkg".format(link_root_name): "isexe",
-        ":.aspect_rules_js/{}/lru-cache@6.0.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/lru-cache@7.17.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/make-fetch-happen@10.2.1/pkg".format(link_root_name): "make-fetch-happen",
-        ":.aspect_rules_js/{}/minimatch@3.1.2/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minimatch@5.1.6/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minipass@3.3.6/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass@4.2.4/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass-collect@1.0.2/pkg".format(link_root_name): "minipass-collect",
-        ":.aspect_rules_js/{}/minipass-fetch@2.1.2/pkg".format(link_root_name): "minipass-fetch",
-        ":.aspect_rules_js/{}/minipass-flush@1.0.5/pkg".format(link_root_name): "minipass-flush",
-        ":.aspect_rules_js/{}/minipass-pipeline@1.2.4/pkg".format(link_root_name): "minipass-pipeline",
-        ":.aspect_rules_js/{}/minipass-sized@1.0.3/pkg".format(link_root_name): "minipass-sized",
-        ":.aspect_rules_js/{}/minizlib@2.1.2/pkg".format(link_root_name): "minizlib",
-        ":.aspect_rules_js/{}/mkdirp@1.0.4/pkg".format(link_root_name): "mkdirp",
-        ":.aspect_rules_js/{}/ms@2.1.3/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/ms@2.1.2/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/nan@2.17.0/pkg".format(link_root_name): "nan",
-        ":.aspect_rules_js/{}/negotiator@0.6.3/pkg".format(link_root_name): "negotiator",
-        ":.aspect_rules_js/{}/node-gyp@9.3.1/pkg".format(link_root_name): "node-gyp",
-        ":.aspect_rules_js/{}/nopt@6.0.0/pkg".format(link_root_name): "nopt",
-        ":.aspect_rules_js/{}/npmlog@6.0.2/pkg".format(link_root_name): "npmlog",
-        ":.aspect_rules_js/{}/once@1.4.0/pkg".format(link_root_name): "once",
-        ":.aspect_rules_js/{}/p-map@4.0.0/pkg".format(link_root_name): "p-map",
-        ":.aspect_rules_js/{}/path-is-absolute@1.0.1/pkg".format(link_root_name): "path-is-absolute",
-        ":.aspect_rules_js/{}/promise-inflight@1.0.1/pkg".format(link_root_name): "promise-inflight",
-        ":.aspect_rules_js/{}/promise-retry@2.0.1/pkg".format(link_root_name): "promise-retry",
-        ":.aspect_rules_js/{}/readable-stream@3.6.1/pkg".format(link_root_name): "readable-stream",
-        ":.aspect_rules_js/{}/retry@0.12.0/pkg".format(link_root_name): "retry",
-        ":.aspect_rules_js/{}/rimraf@3.0.2/pkg".format(link_root_name): "rimraf",
-        ":.aspect_rules_js/{}/safe-buffer@5.2.1/pkg".format(link_root_name): "safe-buffer",
-        ":.aspect_rules_js/{}/safer-buffer@2.1.2/pkg".format(link_root_name): "safer-buffer",
-        ":.aspect_rules_js/{}/segfault-handler@1.3.0/pkg_pre_lc_lite".format(link_root_name): "segfault-handler",
-        ":.aspect_rules_js/{}/semver@7.3.8/pkg".format(link_root_name): "semver",
-        ":.aspect_rules_js/{}/set-blocking@2.0.0/pkg".format(link_root_name): "set-blocking",
-        ":.aspect_rules_js/{}/signal-exit@3.0.7/pkg".format(link_root_name): "signal-exit",
-        ":.aspect_rules_js/{}/smart-buffer@4.2.0/pkg".format(link_root_name): "smart-buffer",
-        ":.aspect_rules_js/{}/socks@2.7.1/pkg".format(link_root_name): "socks",
-        ":.aspect_rules_js/{}/socks-proxy-agent@7.0.0/pkg".format(link_root_name): "socks-proxy-agent",
-        ":.aspect_rules_js/{}/ssri@9.0.1/pkg".format(link_root_name): "ssri",
-        ":.aspect_rules_js/{}/string-width@4.2.3/pkg".format(link_root_name): "string-width",
-        ":.aspect_rules_js/{}/string_decoder@1.3.0/pkg".format(link_root_name): "string_decoder",
-        ":.aspect_rules_js/{}/strip-ansi@6.0.1/pkg".format(link_root_name): "strip-ansi",
-        ":.aspect_rules_js/{}/tar@6.1.13/pkg".format(link_root_name): "tar",
-        ":.aspect_rules_js/{}/unique-filename@2.0.1/pkg".format(link_root_name): "unique-filename",
-        ":.aspect_rules_js/{}/unique-slug@3.0.0/pkg".format(link_root_name): "unique-slug",
-        ":.aspect_rules_js/{}/util-deprecate@1.0.2/pkg".format(link_root_name): "util-deprecate",
-        ":.aspect_rules_js/{}/which@2.0.2/pkg".format(link_root_name): "which",
-        ":.aspect_rules_js/{}/wide-align@1.1.5/pkg".format(link_root_name): "wide-align",
-        ":.aspect_rules_js/{}/wrappy@1.0.2/pkg".format(link_root_name): "wrappy",
-        ":.aspect_rules_js/{}/yallist@4.0.0/pkg".format(link_root_name): "yallist",
-    }
-
-    # pre-lifecycle target with reference deps for use terminal pre-lifecycle target
-    _npm_package_store(
-        name = "{}/pkg_pre_lc_lite".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # terminal pre-lifecycle target for use in lifecycle build target below
-    _npm_package_store(
-        name = "{}/pkg_pre_lc".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = lc_deps,
-        tags = ["manual"],
-    )
-
-    # lifecycle build action
-    _js_run_binary(
-        name = "{}/lc".format(store_target_name),
-        srcs = [
-            "@@aspect_rules_js~~npm~npm__segfault-handler__1.3.0//:pkg",
-            ":{}/pkg_pre_lc".format(store_target_name),
-        ],
-        # js_run_binary runs in the output dir; must add "../../../" because paths are relative to the exec root
-        args = [
-                   "segfault-handler",
-                   "../../../$(execpath @@aspect_rules_js~~npm~npm__segfault-handler__1.3.0//:pkg)",
-                   "../../../$(@D)",
-               ] +
-               select({
-                   Label("@aspect_rules_js//platforms/os:osx"): ["--platform=darwin"],
-                   Label("@aspect_rules_js//platforms/os:linux"): ["--platform=linux"],
-                   Label("@aspect_rules_js//platforms/os:windows"): ["--platform=win32"],
-                   "//conditions:default": [],
-               }) +
-               select({
-                   Label("@aspect_rules_js//platforms/cpu:arm64"): ["--arch=arm64"],
-                   Label("@aspect_rules_js//platforms/cpu:x86_64"): ["--arch=x64"],
-                   "//conditions:default": [],
-               }) +
-               select({
-                   Label("@aspect_rules_js//platforms/libc:glibc"): ["--libc=glibc"],
-                   Label("@aspect_rules_js//platforms/libc:musl"): ["--libc=musl"],
-                   "//conditions:default": [],
-               }),
-        copy_srcs_to_bin = False,
-        tool = Label("@aspect_rules_js//npm/private/lifecycle:lifecycle-hooks"),
-        out_dirs = ["node_modules/.aspect_rules_js/segfault-handler@1.3.0/node_modules/segfault-handler"],
-        tags = ["manual"],
-        execution_requirements = {
+        has_lifecycle_build_target = True,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@aspect_rules_js~~npm~npm__segfault-handler__1.3.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {
             "no-sandbox": "1",
         },
-        mnemonic = "NpmLifecycleHook",
-        progress_message = "Running lifecycle hooks on npm package segfault-handler@1.3.0",
-        env = {},
         use_default_shell_env = True,
-    )
-
-    # post-lifecycle npm_package
-    _npm_package_internal(
-        name = "{}/pkg_lc".format(store_target_name),
-        src = ":{}/lc".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
-        tags = ["manual"],
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package segfault-handler@1.3.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/segfault-handler@1.3.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package segfault-handler@1.3.0
@@ -376,43 +264,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = ""
-    link_packages = {
-        "": ["segfault-handler"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package segfault-handler@1.3.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["segfault-handler"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/e2e/gyp_no_install_script/snapshots/wksp/segfault-handler_defs.bzl b/e2e/gyp_no_install_script/snapshots/wksp/segfault-handler_defs.bzl
index b6004c1..0b87fe3 100644
--- a/e2e/gyp_no_install_script/snapshots/wksp/segfault-handler_defs.bzl
+++ b/e2e/gyp_no_install_script/snapshots/wksp/segfault-handler_defs.bzl
@@ -4,370 +4,258 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
-load("@aspect_rules_js//js:defs.bzl", _js_run_binary = "js_run_binary")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
 
-# buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_package_internal.bzl", _npm_package_internal = "npm_package_internal")
+PACKAGE = "segfault-handler"
+VERSION = "1.3.0"
+_ROOT_PACKAGE = ""
+_PACKAGE_STORE_NAME = "segfault-handler@1.3.0"
 
 # Generated npm_package_store targets for npm package segfault-handler@1.3.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = ""
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package segfault-handler@1.3.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/@gar+promisify@1.1.3/pkg".format(link_root_name): "@gar/promisify",
-        ":.aspect_rules_js/{}/@npmcli+fs@2.1.2/pkg".format(link_root_name): "@npmcli/fs",
-        ":.aspect_rules_js/{}/@npmcli+move-file@2.0.1/pkg".format(link_root_name): "@npmcli/move-file",
-        ":.aspect_rules_js/{}/@tootallnate+once@2.0.0/pkg".format(link_root_name): "@tootallnate/once",
-        ":.aspect_rules_js/{}/abbrev@1.1.1/pkg".format(link_root_name): "abbrev",
-        ":.aspect_rules_js/{}/agent-base@6.0.2/pkg".format(link_root_name): "agent-base",
-        ":.aspect_rules_js/{}/agentkeepalive@4.2.1/pkg".format(link_root_name): "agentkeepalive",
-        ":.aspect_rules_js/{}/aggregate-error@3.1.0/pkg".format(link_root_name): "aggregate-error",
-        ":.aspect_rules_js/{}/ansi-regex@5.0.1/pkg".format(link_root_name): "ansi-regex",
-        ":.aspect_rules_js/{}/aproba@2.0.0/pkg".format(link_root_name): "aproba",
-        ":.aspect_rules_js/{}/are-we-there-yet@3.0.1/pkg".format(link_root_name): "are-we-there-yet",
-        ":.aspect_rules_js/{}/balanced-match@1.0.2/pkg".format(link_root_name): "balanced-match",
-        ":.aspect_rules_js/{}/bindings@1.5.0/pkg".format(link_root_name): "bindings",
-        ":.aspect_rules_js/{}/brace-expansion@1.1.11/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/brace-expansion@2.0.1/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/cacache@16.1.3/pkg".format(link_root_name): "cacache",
-        ":.aspect_rules_js/{}/chownr@2.0.0/pkg".format(link_root_name): "chownr",
-        ":.aspect_rules_js/{}/clean-stack@2.2.0/pkg".format(link_root_name): "clean-stack",
-        ":.aspect_rules_js/{}/color-support@1.1.3/pkg".format(link_root_name): "color-support",
-        ":.aspect_rules_js/{}/concat-map@0.0.1/pkg".format(link_root_name): "concat-map",
-        ":.aspect_rules_js/{}/console-control-strings@1.1.0/pkg".format(link_root_name): "console-control-strings",
-        ":.aspect_rules_js/{}/debug@4.3.4/pkg".format(link_root_name): "debug",
-        ":.aspect_rules_js/{}/delegates@1.0.0/pkg".format(link_root_name): "delegates",
-        ":.aspect_rules_js/{}/depd@1.1.2/pkg".format(link_root_name): "depd",
-        ":.aspect_rules_js/{}/emoji-regex@8.0.0/pkg".format(link_root_name): "emoji-regex",
-        ":.aspect_rules_js/{}/encoding@0.1.13/pkg".format(link_root_name): "encoding",
-        ":.aspect_rules_js/{}/env-paths@2.2.1/pkg".format(link_root_name): "env-paths",
-        ":.aspect_rules_js/{}/err-code@2.0.3/pkg".format(link_root_name): "err-code",
-        ":.aspect_rules_js/{}/file-uri-to-path@1.0.0/pkg".format(link_root_name): "file-uri-to-path",
-        ":.aspect_rules_js/{}/fs-minipass@2.1.0/pkg".format(link_root_name): "fs-minipass",
-        ":.aspect_rules_js/{}/fs.realpath@1.0.0/pkg".format(link_root_name): "fs.realpath",
-        ":.aspect_rules_js/{}/gauge@4.0.4/pkg".format(link_root_name): "gauge",
-        ":.aspect_rules_js/{}/glob@7.2.3/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/glob@8.1.0/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/graceful-fs@4.2.10/pkg".format(link_root_name): "graceful-fs",
-        ":.aspect_rules_js/{}/has-unicode@2.0.1/pkg".format(link_root_name): "has-unicode",
-        ":.aspect_rules_js/{}/http-cache-semantics@4.1.1/pkg".format(link_root_name): "http-cache-semantics",
-        ":.aspect_rules_js/{}/http-proxy-agent@5.0.0/pkg".format(link_root_name): "http-proxy-agent",
-        ":.aspect_rules_js/{}/https-proxy-agent@5.0.1/pkg".format(link_root_name): "https-proxy-agent",
-        ":.aspect_rules_js/{}/humanize-ms@1.2.1/pkg".format(link_root_name): "humanize-ms",
-        ":.aspect_rules_js/{}/iconv-lite@0.6.3/pkg".format(link_root_name): "iconv-lite",
-        ":.aspect_rules_js/{}/imurmurhash@0.1.4/pkg".format(link_root_name): "imurmurhash",
-        ":.aspect_rules_js/{}/indent-string@4.0.0/pkg".format(link_root_name): "indent-string",
-        ":.aspect_rules_js/{}/infer-owner@1.0.4/pkg".format(link_root_name): "infer-owner",
-        ":.aspect_rules_js/{}/inflight@1.0.6/pkg".format(link_root_name): "inflight",
-        ":.aspect_rules_js/{}/inherits@2.0.4/pkg".format(link_root_name): "inherits",
-        ":.aspect_rules_js/{}/ip@2.0.0/pkg".format(link_root_name): "ip",
-        ":.aspect_rules_js/{}/is-fullwidth-code-point@3.0.0/pkg".format(link_root_name): "is-fullwidth-code-point",
-        ":.aspect_rules_js/{}/is-lambda@1.0.1/pkg".format(link_root_name): "is-lambda",
-        ":.aspect_rules_js/{}/isexe@2.0.0/pkg".format(link_root_name): "isexe",
-        ":.aspect_rules_js/{}/lru-cache@6.0.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/lru-cache@7.17.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/make-fetch-happen@10.2.1/pkg".format(link_root_name): "make-fetch-happen",
-        ":.aspect_rules_js/{}/minimatch@3.1.2/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minimatch@5.1.6/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minipass@3.3.6/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass@4.2.4/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass-collect@1.0.2/pkg".format(link_root_name): "minipass-collect",
-        ":.aspect_rules_js/{}/minipass-fetch@2.1.2/pkg".format(link_root_name): "minipass-fetch",
-        ":.aspect_rules_js/{}/minipass-flush@1.0.5/pkg".format(link_root_name): "minipass-flush",
-        ":.aspect_rules_js/{}/minipass-pipeline@1.2.4/pkg".format(link_root_name): "minipass-pipeline",
-        ":.aspect_rules_js/{}/minipass-sized@1.0.3/pkg".format(link_root_name): "minipass-sized",
-        ":.aspect_rules_js/{}/minizlib@2.1.2/pkg".format(link_root_name): "minizlib",
-        ":.aspect_rules_js/{}/mkdirp@1.0.4/pkg".format(link_root_name): "mkdirp",
-        ":.aspect_rules_js/{}/ms@2.1.3/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/ms@2.1.2/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/nan@2.17.0/pkg".format(link_root_name): "nan",
-        ":.aspect_rules_js/{}/negotiator@0.6.3/pkg".format(link_root_name): "negotiator",
-        ":.aspect_rules_js/{}/node-gyp@9.3.1/pkg".format(link_root_name): "node-gyp",
-        ":.aspect_rules_js/{}/nopt@6.0.0/pkg".format(link_root_name): "nopt",
-        ":.aspect_rules_js/{}/npmlog@6.0.2/pkg".format(link_root_name): "npmlog",
-        ":.aspect_rules_js/{}/once@1.4.0/pkg".format(link_root_name): "once",
-        ":.aspect_rules_js/{}/p-map@4.0.0/pkg".format(link_root_name): "p-map",
-        ":.aspect_rules_js/{}/path-is-absolute@1.0.1/pkg".format(link_root_name): "path-is-absolute",
-        ":.aspect_rules_js/{}/promise-inflight@1.0.1/pkg".format(link_root_name): "promise-inflight",
-        ":.aspect_rules_js/{}/promise-retry@2.0.1/pkg".format(link_root_name): "promise-retry",
-        ":.aspect_rules_js/{}/readable-stream@3.6.1/pkg".format(link_root_name): "readable-stream",
-        ":.aspect_rules_js/{}/retry@0.12.0/pkg".format(link_root_name): "retry",
-        ":.aspect_rules_js/{}/rimraf@3.0.2/pkg".format(link_root_name): "rimraf",
-        ":.aspect_rules_js/{}/safe-buffer@5.2.1/pkg".format(link_root_name): "safe-buffer",
-        ":.aspect_rules_js/{}/safer-buffer@2.1.2/pkg".format(link_root_name): "safer-buffer",
-        ":.aspect_rules_js/{}/segfault-handler@1.3.0/pkg".format(link_root_name): "segfault-handler",
-        ":.aspect_rules_js/{}/semver@7.3.8/pkg".format(link_root_name): "semver",
-        ":.aspect_rules_js/{}/set-blocking@2.0.0/pkg".format(link_root_name): "set-blocking",
-        ":.aspect_rules_js/{}/signal-exit@3.0.7/pkg".format(link_root_name): "signal-exit",
-        ":.aspect_rules_js/{}/smart-buffer@4.2.0/pkg".format(link_root_name): "smart-buffer",
-        ":.aspect_rules_js/{}/socks@2.7.1/pkg".format(link_root_name): "socks",
-        ":.aspect_rules_js/{}/socks-proxy-agent@7.0.0/pkg".format(link_root_name): "socks-proxy-agent",
-        ":.aspect_rules_js/{}/ssri@9.0.1/pkg".format(link_root_name): "ssri",
-        ":.aspect_rules_js/{}/string-width@4.2.3/pkg".format(link_root_name): "string-width",
-        ":.aspect_rules_js/{}/string_decoder@1.3.0/pkg".format(link_root_name): "string_decoder",
-        ":.aspect_rules_js/{}/strip-ansi@6.0.1/pkg".format(link_root_name): "strip-ansi",
-        ":.aspect_rules_js/{}/tar@6.1.13/pkg".format(link_root_name): "tar",
-        ":.aspect_rules_js/{}/unique-filename@2.0.1/pkg".format(link_root_name): "unique-filename",
-        ":.aspect_rules_js/{}/unique-slug@3.0.0/pkg".format(link_root_name): "unique-slug",
-        ":.aspect_rules_js/{}/util-deprecate@1.0.2/pkg".format(link_root_name): "util-deprecate",
-        ":.aspect_rules_js/{}/which@2.0.2/pkg".format(link_root_name): "which",
-        ":.aspect_rules_js/{}/wide-align@1.1.5/pkg".format(link_root_name): "wide-align",
-        ":.aspect_rules_js/{}/wrappy@1.0.2/pkg".format(link_root_name): "wrappy",
-        ":.aspect_rules_js/{}/yallist@4.0.0/pkg".format(link_root_name): "yallist",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/bindings@1.5.0/ref".format(link_root_name): "bindings",
-        ":.aspect_rules_js/{}/nan@2.17.0/ref".format(link_root_name): "nan",
-        ":.aspect_rules_js/{}/node-gyp@9.3.1/ref".format(link_root_name): "node-gyp",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/segfault-handler@1.3.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/@gar+promisify@1.1.3/pkg": "@gar/promisify",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+fs@2.1.2/pkg": "@npmcli/fs",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+move-file@2.0.1/pkg": "@npmcli/move-file",
+            ":.aspect_rules_js/{link_root_name}/@tootallnate+once@2.0.0/pkg": "@tootallnate/once",
+            ":.aspect_rules_js/{link_root_name}/abbrev@1.1.1/pkg": "abbrev",
+            ":.aspect_rules_js/{link_root_name}/agent-base@6.0.2/pkg": "agent-base",
+            ":.aspect_rules_js/{link_root_name}/agentkeepalive@4.2.1/pkg": "agentkeepalive",
+            ":.aspect_rules_js/{link_root_name}/aggregate-error@3.1.0/pkg": "aggregate-error",
+            ":.aspect_rules_js/{link_root_name}/ansi-regex@5.0.1/pkg": "ansi-regex",
+            ":.aspect_rules_js/{link_root_name}/aproba@2.0.0/pkg": "aproba",
+            ":.aspect_rules_js/{link_root_name}/are-we-there-yet@3.0.1/pkg": "are-we-there-yet",
+            ":.aspect_rules_js/{link_root_name}/balanced-match@1.0.2/pkg": "balanced-match",
+            ":.aspect_rules_js/{link_root_name}/bindings@1.5.0/pkg": "bindings",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@1.1.11/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@2.0.1/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/cacache@16.1.3/pkg": "cacache",
+            ":.aspect_rules_js/{link_root_name}/chownr@2.0.0/pkg": "chownr",
+            ":.aspect_rules_js/{link_root_name}/clean-stack@2.2.0/pkg": "clean-stack",
+            ":.aspect_rules_js/{link_root_name}/color-support@1.1.3/pkg": "color-support",
+            ":.aspect_rules_js/{link_root_name}/concat-map@0.0.1/pkg": "concat-map",
+            ":.aspect_rules_js/{link_root_name}/console-control-strings@1.1.0/pkg": "console-control-strings",
+            ":.aspect_rules_js/{link_root_name}/debug@4.3.4/pkg": "debug",
+            ":.aspect_rules_js/{link_root_name}/delegates@1.0.0/pkg": "delegates",
+            ":.aspect_rules_js/{link_root_name}/depd@1.1.2/pkg": "depd",
+            ":.aspect_rules_js/{link_root_name}/emoji-regex@8.0.0/pkg": "emoji-regex",
+            ":.aspect_rules_js/{link_root_name}/encoding@0.1.13/pkg": "encoding",
+            ":.aspect_rules_js/{link_root_name}/env-paths@2.2.1/pkg": "env-paths",
+            ":.aspect_rules_js/{link_root_name}/err-code@2.0.3/pkg": "err-code",
+            ":.aspect_rules_js/{link_root_name}/file-uri-to-path@1.0.0/pkg": "file-uri-to-path",
+            ":.aspect_rules_js/{link_root_name}/fs-minipass@2.1.0/pkg": "fs-minipass",
+            ":.aspect_rules_js/{link_root_name}/fs.realpath@1.0.0/pkg": "fs.realpath",
+            ":.aspect_rules_js/{link_root_name}/gauge@4.0.4/pkg": "gauge",
+            ":.aspect_rules_js/{link_root_name}/glob@7.2.3/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/glob@8.1.0/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/graceful-fs@4.2.10/pkg": "graceful-fs",
+            ":.aspect_rules_js/{link_root_name}/has-unicode@2.0.1/pkg": "has-unicode",
+            ":.aspect_rules_js/{link_root_name}/http-cache-semantics@4.1.1/pkg": "http-cache-semantics",
+            ":.aspect_rules_js/{link_root_name}/http-proxy-agent@5.0.0/pkg": "http-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/https-proxy-agent@5.0.1/pkg": "https-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/humanize-ms@1.2.1/pkg": "humanize-ms",
+            ":.aspect_rules_js/{link_root_name}/iconv-lite@0.6.3/pkg": "iconv-lite",
+            ":.aspect_rules_js/{link_root_name}/imurmurhash@0.1.4/pkg": "imurmurhash",
+            ":.aspect_rules_js/{link_root_name}/indent-string@4.0.0/pkg": "indent-string",
+            ":.aspect_rules_js/{link_root_name}/infer-owner@1.0.4/pkg": "infer-owner",
+            ":.aspect_rules_js/{link_root_name}/inflight@1.0.6/pkg": "inflight",
+            ":.aspect_rules_js/{link_root_name}/inherits@2.0.4/pkg": "inherits",
+            ":.aspect_rules_js/{link_root_name}/ip@2.0.0/pkg": "ip",
+            ":.aspect_rules_js/{link_root_name}/is-fullwidth-code-point@3.0.0/pkg": "is-fullwidth-code-point",
+            ":.aspect_rules_js/{link_root_name}/is-lambda@1.0.1/pkg": "is-lambda",
+            ":.aspect_rules_js/{link_root_name}/isexe@2.0.0/pkg": "isexe",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@6.0.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@7.17.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/make-fetch-happen@10.2.1/pkg": "make-fetch-happen",
+            ":.aspect_rules_js/{link_root_name}/minimatch@3.1.2/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minimatch@5.1.6/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minipass@3.3.6/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass@4.2.4/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass-collect@1.0.2/pkg": "minipass-collect",
+            ":.aspect_rules_js/{link_root_name}/minipass-fetch@2.1.2/pkg": "minipass-fetch",
+            ":.aspect_rules_js/{link_root_name}/minipass-flush@1.0.5/pkg": "minipass-flush",
+            ":.aspect_rules_js/{link_root_name}/minipass-pipeline@1.2.4/pkg": "minipass-pipeline",
+            ":.aspect_rules_js/{link_root_name}/minipass-sized@1.0.3/pkg": "minipass-sized",
+            ":.aspect_rules_js/{link_root_name}/minizlib@2.1.2/pkg": "minizlib",
+            ":.aspect_rules_js/{link_root_name}/mkdirp@1.0.4/pkg": "mkdirp",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.3/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.2/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/nan@2.17.0/pkg": "nan",
+            ":.aspect_rules_js/{link_root_name}/negotiator@0.6.3/pkg": "negotiator",
+            ":.aspect_rules_js/{link_root_name}/node-gyp@9.3.1/pkg": "node-gyp",
+            ":.aspect_rules_js/{link_root_name}/nopt@6.0.0/pkg": "nopt",
+            ":.aspect_rules_js/{link_root_name}/npmlog@6.0.2/pkg": "npmlog",
+            ":.aspect_rules_js/{link_root_name}/once@1.4.0/pkg": "once",
+            ":.aspect_rules_js/{link_root_name}/p-map@4.0.0/pkg": "p-map",
+            ":.aspect_rules_js/{link_root_name}/path-is-absolute@1.0.1/pkg": "path-is-absolute",
+            ":.aspect_rules_js/{link_root_name}/promise-inflight@1.0.1/pkg": "promise-inflight",
+            ":.aspect_rules_js/{link_root_name}/promise-retry@2.0.1/pkg": "promise-retry",
+            ":.aspect_rules_js/{link_root_name}/readable-stream@3.6.1/pkg": "readable-stream",
+            ":.aspect_rules_js/{link_root_name}/retry@0.12.0/pkg": "retry",
+            ":.aspect_rules_js/{link_root_name}/rimraf@3.0.2/pkg": "rimraf",
+            ":.aspect_rules_js/{link_root_name}/safe-buffer@5.2.1/pkg": "safe-buffer",
+            ":.aspect_rules_js/{link_root_name}/safer-buffer@2.1.2/pkg": "safer-buffer",
+            ":.aspect_rules_js/{link_root_name}/segfault-handler@1.3.0/pkg": "segfault-handler",
+            ":.aspect_rules_js/{link_root_name}/semver@7.3.8/pkg": "semver",
+            ":.aspect_rules_js/{link_root_name}/set-blocking@2.0.0/pkg": "set-blocking",
+            ":.aspect_rules_js/{link_root_name}/signal-exit@3.0.7/pkg": "signal-exit",
+            ":.aspect_rules_js/{link_root_name}/smart-buffer@4.2.0/pkg": "smart-buffer",
+            ":.aspect_rules_js/{link_root_name}/socks@2.7.1/pkg": "socks",
+            ":.aspect_rules_js/{link_root_name}/socks-proxy-agent@7.0.0/pkg": "socks-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/ssri@9.0.1/pkg": "ssri",
+            ":.aspect_rules_js/{link_root_name}/string-width@4.2.3/pkg": "string-width",
+            ":.aspect_rules_js/{link_root_name}/string_decoder@1.3.0/pkg": "string_decoder",
+            ":.aspect_rules_js/{link_root_name}/strip-ansi@6.0.1/pkg": "strip-ansi",
+            ":.aspect_rules_js/{link_root_name}/tar@6.1.13/pkg": "tar",
+            ":.aspect_rules_js/{link_root_name}/unique-filename@2.0.1/pkg": "unique-filename",
+            ":.aspect_rules_js/{link_root_name}/unique-slug@3.0.0/pkg": "unique-slug",
+            ":.aspect_rules_js/{link_root_name}/util-deprecate@1.0.2/pkg": "util-deprecate",
+            ":.aspect_rules_js/{link_root_name}/which@2.0.2/pkg": "which",
+            ":.aspect_rules_js/{link_root_name}/wide-align@1.1.5/pkg": "wide-align",
+            ":.aspect_rules_js/{link_root_name}/wrappy@1.0.2/pkg": "wrappy",
+            ":.aspect_rules_js/{link_root_name}/yallist@4.0.0/pkg": "yallist",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/bindings@1.5.0/ref": "bindings",
+            ":.aspect_rules_js/{link_root_name}/nan@2.17.0/ref": "nan",
+            ":.aspect_rules_js/{link_root_name}/node-gyp@9.3.1/ref": "node-gyp",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/@gar+promisify@1.1.3/pkg": "@gar/promisify",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+fs@2.1.2/pkg": "@npmcli/fs",
+            ":.aspect_rules_js/{link_root_name}/@npmcli+move-file@2.0.1/pkg": "@npmcli/move-file",
+            ":.aspect_rules_js/{link_root_name}/@tootallnate+once@2.0.0/pkg": "@tootallnate/once",
+            ":.aspect_rules_js/{link_root_name}/abbrev@1.1.1/pkg": "abbrev",
+            ":.aspect_rules_js/{link_root_name}/agent-base@6.0.2/pkg": "agent-base",
+            ":.aspect_rules_js/{link_root_name}/agentkeepalive@4.2.1/pkg": "agentkeepalive",
+            ":.aspect_rules_js/{link_root_name}/aggregate-error@3.1.0/pkg": "aggregate-error",
+            ":.aspect_rules_js/{link_root_name}/ansi-regex@5.0.1/pkg": "ansi-regex",
+            ":.aspect_rules_js/{link_root_name}/aproba@2.0.0/pkg": "aproba",
+            ":.aspect_rules_js/{link_root_name}/are-we-there-yet@3.0.1/pkg": "are-we-there-yet",
+            ":.aspect_rules_js/{link_root_name}/balanced-match@1.0.2/pkg": "balanced-match",
+            ":.aspect_rules_js/{link_root_name}/bindings@1.5.0/pkg": "bindings",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@1.1.11/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/brace-expansion@2.0.1/pkg": "brace-expansion",
+            ":.aspect_rules_js/{link_root_name}/cacache@16.1.3/pkg": "cacache",
+            ":.aspect_rules_js/{link_root_name}/chownr@2.0.0/pkg": "chownr",
+            ":.aspect_rules_js/{link_root_name}/clean-stack@2.2.0/pkg": "clean-stack",
+            ":.aspect_rules_js/{link_root_name}/color-support@1.1.3/pkg": "color-support",
+            ":.aspect_rules_js/{link_root_name}/concat-map@0.0.1/pkg": "concat-map",
+            ":.aspect_rules_js/{link_root_name}/console-control-strings@1.1.0/pkg": "console-control-strings",
+            ":.aspect_rules_js/{link_root_name}/debug@4.3.4/pkg": "debug",
+            ":.aspect_rules_js/{link_root_name}/delegates@1.0.0/pkg": "delegates",
+            ":.aspect_rules_js/{link_root_name}/depd@1.1.2/pkg": "depd",
+            ":.aspect_rules_js/{link_root_name}/emoji-regex@8.0.0/pkg": "emoji-regex",
+            ":.aspect_rules_js/{link_root_name}/encoding@0.1.13/pkg": "encoding",
+            ":.aspect_rules_js/{link_root_name}/env-paths@2.2.1/pkg": "env-paths",
+            ":.aspect_rules_js/{link_root_name}/err-code@2.0.3/pkg": "err-code",
+            ":.aspect_rules_js/{link_root_name}/file-uri-to-path@1.0.0/pkg": "file-uri-to-path",
+            ":.aspect_rules_js/{link_root_name}/fs-minipass@2.1.0/pkg": "fs-minipass",
+            ":.aspect_rules_js/{link_root_name}/fs.realpath@1.0.0/pkg": "fs.realpath",
+            ":.aspect_rules_js/{link_root_name}/gauge@4.0.4/pkg": "gauge",
+            ":.aspect_rules_js/{link_root_name}/glob@7.2.3/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/glob@8.1.0/pkg": "glob",
+            ":.aspect_rules_js/{link_root_name}/graceful-fs@4.2.10/pkg": "graceful-fs",
+            ":.aspect_rules_js/{link_root_name}/has-unicode@2.0.1/pkg": "has-unicode",
+            ":.aspect_rules_js/{link_root_name}/http-cache-semantics@4.1.1/pkg": "http-cache-semantics",
+            ":.aspect_rules_js/{link_root_name}/http-proxy-agent@5.0.0/pkg": "http-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/https-proxy-agent@5.0.1/pkg": "https-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/humanize-ms@1.2.1/pkg": "humanize-ms",
+            ":.aspect_rules_js/{link_root_name}/iconv-lite@0.6.3/pkg": "iconv-lite",
+            ":.aspect_rules_js/{link_root_name}/imurmurhash@0.1.4/pkg": "imurmurhash",
+            ":.aspect_rules_js/{link_root_name}/indent-string@4.0.0/pkg": "indent-string",
+            ":.aspect_rules_js/{link_root_name}/infer-owner@1.0.4/pkg": "infer-owner",
+            ":.aspect_rules_js/{link_root_name}/inflight@1.0.6/pkg": "inflight",
+            ":.aspect_rules_js/{link_root_name}/inherits@2.0.4/pkg": "inherits",
+            ":.aspect_rules_js/{link_root_name}/ip@2.0.0/pkg": "ip",
+            ":.aspect_rules_js/{link_root_name}/is-fullwidth-code-point@3.0.0/pkg": "is-fullwidth-code-point",
+            ":.aspect_rules_js/{link_root_name}/is-lambda@1.0.1/pkg": "is-lambda",
+            ":.aspect_rules_js/{link_root_name}/isexe@2.0.0/pkg": "isexe",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@6.0.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/lru-cache@7.17.0/pkg": "lru-cache",
+            ":.aspect_rules_js/{link_root_name}/make-fetch-happen@10.2.1/pkg": "make-fetch-happen",
+            ":.aspect_rules_js/{link_root_name}/minimatch@3.1.2/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minimatch@5.1.6/pkg": "minimatch",
+            ":.aspect_rules_js/{link_root_name}/minipass@3.3.6/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass@4.2.4/pkg": "minipass",
+            ":.aspect_rules_js/{link_root_name}/minipass-collect@1.0.2/pkg": "minipass-collect",
+            ":.aspect_rules_js/{link_root_name}/minipass-fetch@2.1.2/pkg": "minipass-fetch",
+            ":.aspect_rules_js/{link_root_name}/minipass-flush@1.0.5/pkg": "minipass-flush",
+            ":.aspect_rules_js/{link_root_name}/minipass-pipeline@1.2.4/pkg": "minipass-pipeline",
+            ":.aspect_rules_js/{link_root_name}/minipass-sized@1.0.3/pkg": "minipass-sized",
+            ":.aspect_rules_js/{link_root_name}/minizlib@2.1.2/pkg": "minizlib",
+            ":.aspect_rules_js/{link_root_name}/mkdirp@1.0.4/pkg": "mkdirp",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.3/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/ms@2.1.2/pkg": "ms",
+            ":.aspect_rules_js/{link_root_name}/nan@2.17.0/pkg": "nan",
+            ":.aspect_rules_js/{link_root_name}/negotiator@0.6.3/pkg": "negotiator",
+            ":.aspect_rules_js/{link_root_name}/node-gyp@9.3.1/pkg": "node-gyp",
+            ":.aspect_rules_js/{link_root_name}/nopt@6.0.0/pkg": "nopt",
+            ":.aspect_rules_js/{link_root_name}/npmlog@6.0.2/pkg": "npmlog",
+            ":.aspect_rules_js/{link_root_name}/once@1.4.0/pkg": "once",
+            ":.aspect_rules_js/{link_root_name}/p-map@4.0.0/pkg": "p-map",
+            ":.aspect_rules_js/{link_root_name}/path-is-absolute@1.0.1/pkg": "path-is-absolute",
+            ":.aspect_rules_js/{link_root_name}/promise-inflight@1.0.1/pkg": "promise-inflight",
+            ":.aspect_rules_js/{link_root_name}/promise-retry@2.0.1/pkg": "promise-retry",
+            ":.aspect_rules_js/{link_root_name}/readable-stream@3.6.1/pkg": "readable-stream",
+            ":.aspect_rules_js/{link_root_name}/retry@0.12.0/pkg": "retry",
+            ":.aspect_rules_js/{link_root_name}/rimraf@3.0.2/pkg": "rimraf",
+            ":.aspect_rules_js/{link_root_name}/safe-buffer@5.2.1/pkg": "safe-buffer",
+            ":.aspect_rules_js/{link_root_name}/safer-buffer@2.1.2/pkg": "safer-buffer",
+            ":.aspect_rules_js/{link_root_name}/segfault-handler@1.3.0/pkg_pre_lc_lite": "segfault-handler",
+            ":.aspect_rules_js/{link_root_name}/semver@7.3.8/pkg": "semver",
+            ":.aspect_rules_js/{link_root_name}/set-blocking@2.0.0/pkg": "set-blocking",
+            ":.aspect_rules_js/{link_root_name}/signal-exit@3.0.7/pkg": "signal-exit",
+            ":.aspect_rules_js/{link_root_name}/smart-buffer@4.2.0/pkg": "smart-buffer",
+            ":.aspect_rules_js/{link_root_name}/socks@2.7.1/pkg": "socks",
+            ":.aspect_rules_js/{link_root_name}/socks-proxy-agent@7.0.0/pkg": "socks-proxy-agent",
+            ":.aspect_rules_js/{link_root_name}/ssri@9.0.1/pkg": "ssri",
+            ":.aspect_rules_js/{link_root_name}/string-width@4.2.3/pkg": "string-width",
+            ":.aspect_rules_js/{link_root_name}/string_decoder@1.3.0/pkg": "string_decoder",
+            ":.aspect_rules_js/{link_root_name}/strip-ansi@6.0.1/pkg": "strip-ansi",
+            ":.aspect_rules_js/{link_root_name}/tar@6.1.13/pkg": "tar",
+            ":.aspect_rules_js/{link_root_name}/unique-filename@2.0.1/pkg": "unique-filename",
+            ":.aspect_rules_js/{link_root_name}/unique-slug@3.0.0/pkg": "unique-slug",
+            ":.aspect_rules_js/{link_root_name}/util-deprecate@1.0.2/pkg": "util-deprecate",
+            ":.aspect_rules_js/{link_root_name}/which@2.0.2/pkg": "which",
+            ":.aspect_rules_js/{link_root_name}/wide-align@1.1.5/pkg": "wide-align",
+            ":.aspect_rules_js/{link_root_name}/wrappy@1.0.2/pkg": "wrappy",
+            ":.aspect_rules_js/{link_root_name}/yallist@4.0.0/pkg": "yallist",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if True else "@@npm__segfault-handler__1.3.0//:pkg",
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@npm__segfault-handler__1.3.0//:pkg",
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    lc_deps = {
-        ":.aspect_rules_js/{}/@gar+promisify@1.1.3/pkg".format(link_root_name): "@gar/promisify",
-        ":.aspect_rules_js/{}/@npmcli+fs@2.1.2/pkg".format(link_root_name): "@npmcli/fs",
-        ":.aspect_rules_js/{}/@npmcli+move-file@2.0.1/pkg".format(link_root_name): "@npmcli/move-file",
-        ":.aspect_rules_js/{}/@tootallnate+once@2.0.0/pkg".format(link_root_name): "@tootallnate/once",
-        ":.aspect_rules_js/{}/abbrev@1.1.1/pkg".format(link_root_name): "abbrev",
-        ":.aspect_rules_js/{}/agent-base@6.0.2/pkg".format(link_root_name): "agent-base",
-        ":.aspect_rules_js/{}/agentkeepalive@4.2.1/pkg".format(link_root_name): "agentkeepalive",
-        ":.aspect_rules_js/{}/aggregate-error@3.1.0/pkg".format(link_root_name): "aggregate-error",
-        ":.aspect_rules_js/{}/ansi-regex@5.0.1/pkg".format(link_root_name): "ansi-regex",
-        ":.aspect_rules_js/{}/aproba@2.0.0/pkg".format(link_root_name): "aproba",
-        ":.aspect_rules_js/{}/are-we-there-yet@3.0.1/pkg".format(link_root_name): "are-we-there-yet",
-        ":.aspect_rules_js/{}/balanced-match@1.0.2/pkg".format(link_root_name): "balanced-match",
-        ":.aspect_rules_js/{}/bindings@1.5.0/pkg".format(link_root_name): "bindings",
-        ":.aspect_rules_js/{}/brace-expansion@1.1.11/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/brace-expansion@2.0.1/pkg".format(link_root_name): "brace-expansion",
-        ":.aspect_rules_js/{}/cacache@16.1.3/pkg".format(link_root_name): "cacache",
-        ":.aspect_rules_js/{}/chownr@2.0.0/pkg".format(link_root_name): "chownr",
-        ":.aspect_rules_js/{}/clean-stack@2.2.0/pkg".format(link_root_name): "clean-stack",
-        ":.aspect_rules_js/{}/color-support@1.1.3/pkg".format(link_root_name): "color-support",
-        ":.aspect_rules_js/{}/concat-map@0.0.1/pkg".format(link_root_name): "concat-map",
-        ":.aspect_rules_js/{}/console-control-strings@1.1.0/pkg".format(link_root_name): "console-control-strings",
-        ":.aspect_rules_js/{}/debug@4.3.4/pkg".format(link_root_name): "debug",
-        ":.aspect_rules_js/{}/delegates@1.0.0/pkg".format(link_root_name): "delegates",
-        ":.aspect_rules_js/{}/depd@1.1.2/pkg".format(link_root_name): "depd",
-        ":.aspect_rules_js/{}/emoji-regex@8.0.0/pkg".format(link_root_name): "emoji-regex",
-        ":.aspect_rules_js/{}/encoding@0.1.13/pkg".format(link_root_name): "encoding",
-        ":.aspect_rules_js/{}/env-paths@2.2.1/pkg".format(link_root_name): "env-paths",
-        ":.aspect_rules_js/{}/err-code@2.0.3/pkg".format(link_root_name): "err-code",
-        ":.aspect_rules_js/{}/file-uri-to-path@1.0.0/pkg".format(link_root_name): "file-uri-to-path",
-        ":.aspect_rules_js/{}/fs-minipass@2.1.0/pkg".format(link_root_name): "fs-minipass",
-        ":.aspect_rules_js/{}/fs.realpath@1.0.0/pkg".format(link_root_name): "fs.realpath",
-        ":.aspect_rules_js/{}/gauge@4.0.4/pkg".format(link_root_name): "gauge",
-        ":.aspect_rules_js/{}/glob@7.2.3/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/glob@8.1.0/pkg".format(link_root_name): "glob",
-        ":.aspect_rules_js/{}/graceful-fs@4.2.10/pkg".format(link_root_name): "graceful-fs",
-        ":.aspect_rules_js/{}/has-unicode@2.0.1/pkg".format(link_root_name): "has-unicode",
-        ":.aspect_rules_js/{}/http-cache-semantics@4.1.1/pkg".format(link_root_name): "http-cache-semantics",
-        ":.aspect_rules_js/{}/http-proxy-agent@5.0.0/pkg".format(link_root_name): "http-proxy-agent",
-        ":.aspect_rules_js/{}/https-proxy-agent@5.0.1/pkg".format(link_root_name): "https-proxy-agent",
-        ":.aspect_rules_js/{}/humanize-ms@1.2.1/pkg".format(link_root_name): "humanize-ms",
-        ":.aspect_rules_js/{}/iconv-lite@0.6.3/pkg".format(link_root_name): "iconv-lite",
-        ":.aspect_rules_js/{}/imurmurhash@0.1.4/pkg".format(link_root_name): "imurmurhash",
-        ":.aspect_rules_js/{}/indent-string@4.0.0/pkg".format(link_root_name): "indent-string",
-        ":.aspect_rules_js/{}/infer-owner@1.0.4/pkg".format(link_root_name): "infer-owner",
-        ":.aspect_rules_js/{}/inflight@1.0.6/pkg".format(link_root_name): "inflight",
-        ":.aspect_rules_js/{}/inherits@2.0.4/pkg".format(link_root_name): "inherits",
-        ":.aspect_rules_js/{}/ip@2.0.0/pkg".format(link_root_name): "ip",
-        ":.aspect_rules_js/{}/is-fullwidth-code-point@3.0.0/pkg".format(link_root_name): "is-fullwidth-code-point",
-        ":.aspect_rules_js/{}/is-lambda@1.0.1/pkg".format(link_root_name): "is-lambda",
-        ":.aspect_rules_js/{}/isexe@2.0.0/pkg".format(link_root_name): "isexe",
-        ":.aspect_rules_js/{}/lru-cache@6.0.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/lru-cache@7.17.0/pkg".format(link_root_name): "lru-cache",
-        ":.aspect_rules_js/{}/make-fetch-happen@10.2.1/pkg".format(link_root_name): "make-fetch-happen",
-        ":.aspect_rules_js/{}/minimatch@3.1.2/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minimatch@5.1.6/pkg".format(link_root_name): "minimatch",
-        ":.aspect_rules_js/{}/minipass@3.3.6/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass@4.2.4/pkg".format(link_root_name): "minipass",
-        ":.aspect_rules_js/{}/minipass-collect@1.0.2/pkg".format(link_root_name): "minipass-collect",
-        ":.aspect_rules_js/{}/minipass-fetch@2.1.2/pkg".format(link_root_name): "minipass-fetch",
-        ":.aspect_rules_js/{}/minipass-flush@1.0.5/pkg".format(link_root_name): "minipass-flush",
-        ":.aspect_rules_js/{}/minipass-pipeline@1.2.4/pkg".format(link_root_name): "minipass-pipeline",
-        ":.aspect_rules_js/{}/minipass-sized@1.0.3/pkg".format(link_root_name): "minipass-sized",
-        ":.aspect_rules_js/{}/minizlib@2.1.2/pkg".format(link_root_name): "minizlib",
-        ":.aspect_rules_js/{}/mkdirp@1.0.4/pkg".format(link_root_name): "mkdirp",
-        ":.aspect_rules_js/{}/ms@2.1.3/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/ms@2.1.2/pkg".format(link_root_name): "ms",
-        ":.aspect_rules_js/{}/nan@2.17.0/pkg".format(link_root_name): "nan",
-        ":.aspect_rules_js/{}/negotiator@0.6.3/pkg".format(link_root_name): "negotiator",
-        ":.aspect_rules_js/{}/node-gyp@9.3.1/pkg".format(link_root_name): "node-gyp",
-        ":.aspect_rules_js/{}/nopt@6.0.0/pkg".format(link_root_name): "nopt",
-        ":.aspect_rules_js/{}/npmlog@6.0.2/pkg".format(link_root_name): "npmlog",
-        ":.aspect_rules_js/{}/once@1.4.0/pkg".format(link_root_name): "once",
-        ":.aspect_rules_js/{}/p-map@4.0.0/pkg".format(link_root_name): "p-map",
-        ":.aspect_rules_js/{}/path-is-absolute@1.0.1/pkg".format(link_root_name): "path-is-absolute",
-        ":.aspect_rules_js/{}/promise-inflight@1.0.1/pkg".format(link_root_name): "promise-inflight",
-        ":.aspect_rules_js/{}/promise-retry@2.0.1/pkg".format(link_root_name): "promise-retry",
-        ":.aspect_rules_js/{}/readable-stream@3.6.1/pkg".format(link_root_name): "readable-stream",
-        ":.aspect_rules_js/{}/retry@0.12.0/pkg".format(link_root_name): "retry",
-        ":.aspect_rules_js/{}/rimraf@3.0.2/pkg".format(link_root_name): "rimraf",
-        ":.aspect_rules_js/{}/safe-buffer@5.2.1/pkg".format(link_root_name): "safe-buffer",
-        ":.aspect_rules_js/{}/safer-buffer@2.1.2/pkg".format(link_root_name): "safer-buffer",
-        ":.aspect_rules_js/{}/segfault-handler@1.3.0/pkg_pre_lc_lite".format(link_root_name): "segfault-handler",
-        ":.aspect_rules_js/{}/semver@7.3.8/pkg".format(link_root_name): "semver",
-        ":.aspect_rules_js/{}/set-blocking@2.0.0/pkg".format(link_root_name): "set-blocking",
-        ":.aspect_rules_js/{}/signal-exit@3.0.7/pkg".format(link_root_name): "signal-exit",
-        ":.aspect_rules_js/{}/smart-buffer@4.2.0/pkg".format(link_root_name): "smart-buffer",
-        ":.aspect_rules_js/{}/socks@2.7.1/pkg".format(link_root_name): "socks",
-        ":.aspect_rules_js/{}/socks-proxy-agent@7.0.0/pkg".format(link_root_name): "socks-proxy-agent",
-        ":.aspect_rules_js/{}/ssri@9.0.1/pkg".format(link_root_name): "ssri",
-        ":.aspect_rules_js/{}/string-width@4.2.3/pkg".format(link_root_name): "string-width",
-        ":.aspect_rules_js/{}/string_decoder@1.3.0/pkg".format(link_root_name): "string_decoder",
-        ":.aspect_rules_js/{}/strip-ansi@6.0.1/pkg".format(link_root_name): "strip-ansi",
-        ":.aspect_rules_js/{}/tar@6.1.13/pkg".format(link_root_name): "tar",
-        ":.aspect_rules_js/{}/unique-filename@2.0.1/pkg".format(link_root_name): "unique-filename",
-        ":.aspect_rules_js/{}/unique-slug@3.0.0/pkg".format(link_root_name): "unique-slug",
-        ":.aspect_rules_js/{}/util-deprecate@1.0.2/pkg".format(link_root_name): "util-deprecate",
-        ":.aspect_rules_js/{}/which@2.0.2/pkg".format(link_root_name): "which",
-        ":.aspect_rules_js/{}/wide-align@1.1.5/pkg".format(link_root_name): "wide-align",
-        ":.aspect_rules_js/{}/wrappy@1.0.2/pkg".format(link_root_name): "wrappy",
-        ":.aspect_rules_js/{}/yallist@4.0.0/pkg".format(link_root_name): "yallist",
-    }
-
-    # pre-lifecycle target with reference deps for use terminal pre-lifecycle target
-    _npm_package_store(
-        name = "{}/pkg_pre_lc_lite".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # terminal pre-lifecycle target for use in lifecycle build target below
-    _npm_package_store(
-        name = "{}/pkg_pre_lc".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
-        dev = False,
-        deps = lc_deps,
-        tags = ["manual"],
-    )
-
-    # lifecycle build action
-    _js_run_binary(
-        name = "{}/lc".format(store_target_name),
-        srcs = [
-            "@@npm__segfault-handler__1.3.0//:pkg",
-            ":{}/pkg_pre_lc".format(store_target_name),
-        ],
-        # js_run_binary runs in the output dir; must add "../../../" because paths are relative to the exec root
-        args = [
-                   "segfault-handler",
-                   "../../../$(execpath @@npm__segfault-handler__1.3.0//:pkg)",
-                   "../../../$(@D)",
-               ] +
-               select({
-                   Label("@aspect_rules_js//platforms/os:osx"): ["--platform=darwin"],
-                   Label("@aspect_rules_js//platforms/os:linux"): ["--platform=linux"],
-                   Label("@aspect_rules_js//platforms/os:windows"): ["--platform=win32"],
-                   "//conditions:default": [],
-               }) +
-               select({
-                   Label("@aspect_rules_js//platforms/cpu:arm64"): ["--arch=arm64"],
-                   Label("@aspect_rules_js//platforms/cpu:x86_64"): ["--arch=x64"],
-                   "//conditions:default": [],
-               }) +
-               select({
-                   Label("@aspect_rules_js//platforms/libc:glibc"): ["--libc=glibc"],
-                   Label("@aspect_rules_js//platforms/libc:musl"): ["--libc=musl"],
-                   "//conditions:default": [],
-               }),
-        copy_srcs_to_bin = False,
-        tool = Label("@aspect_rules_js//npm/private/lifecycle:lifecycle-hooks"),
-        out_dirs = ["node_modules/.aspect_rules_js/segfault-handler@1.3.0/node_modules/segfault-handler"],
-        tags = ["manual"],
-        execution_requirements = {
+        has_lifecycle_build_target = True,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@npm__segfault-handler__1.3.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {
             "no-sandbox": "1",
         },
-        mnemonic = "NpmLifecycleHook",
-        progress_message = "Running lifecycle hooks on npm package segfault-handler@1.3.0",
-        env = {},
         use_default_shell_env = True,
-    )
-
-    # post-lifecycle npm_package
-    _npm_package_internal(
-        name = "{}/pkg_lc".format(store_target_name),
-        src = ":{}/lc".format(store_target_name),
-        package = "segfault-handler",
-        version = "1.3.0",
-        tags = ["manual"],
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package segfault-handler@1.3.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/segfault-handler@1.3.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package segfault-handler@1.3.0
@@ -376,43 +264,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = ""
-    link_packages = {
-        "": ["segfault-handler"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package segfault-handler@1.3.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["segfault-handler"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/e2e/npm_translate_lock_disable_hooks/snapshots/aspect_test_c_links_defs.bzl b/e2e/npm_translate_lock_disable_hooks/snapshots/aspect_test_c_links_defs.bzl
index f03c90e..64e199f 100644
--- a/e2e/npm_translate_lock_disable_hooks/snapshots/aspect_test_c_links_defs.bzl
+++ b/e2e/npm_translate_lock_disable_hooks/snapshots/aspect_test_c_links_defs.bzl
@@ -4,89 +4,54 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "@aspect-test/c"
+VERSION = "2.0.0"
+_ROOT_PACKAGE = ""
+_PACKAGE_STORE_NAME = "@aspect-test+c@2.0.0"
 
 # Generated npm_package_store targets for npm package @aspect-test/c@2.0.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = ""
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package @aspect-test/c@2.0.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/@aspect-test+c@2.0.0/pkg".format(link_root_name): "@aspect-test/c",
-    }
-    ref_deps = {}
-
-    store_target_name = ".aspect_rules_js/{}/@aspect-test+c@2.0.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "@aspect-test/c",
-        version = "2.0.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/@aspect-test+c@2.0.0/pkg": "@aspect-test/c",
+        },
+        ref_deps = {},
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/@aspect-test+c@2.0.0/pkg_pre_lc_lite": "@aspect-test/c",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@aspect_rules_js~~npm~npm__at_aspect-test_c__2.0.0//:pkg",
-        package = "@aspect-test/c",
-        version = "2.0.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@aspect_rules_js~~npm~npm__at_aspect-test_c__2.0.0//:pkg",
-        package = "@aspect-test/c",
-        version = "2.0.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@aspect_rules_js~~npm~npm__at_aspect-test_c__2.0.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package @aspect-test/c@2.0.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/@aspect-test+c@2.0.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package @aspect-test/c@2.0.0
@@ -95,43 +60,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = ""
-    link_packages = {
-        "": ["@aspect-test/c"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package @aspect-test/c@2.0.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["@aspect-test/c"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/e2e/pnpm_lockfiles/v54/snapshots/rollup_links_defs.bzl b/e2e/pnpm_lockfiles/v54/snapshots/rollup_links_defs.bzl
index 5fd4bbd..60ebee0 100644
--- a/e2e/pnpm_lockfiles/v54/snapshots/rollup_links_defs.bzl
+++ b/e2e/pnpm_lockfiles/v54/snapshots/rollup_links_defs.bzl
@@ -4,92 +4,58 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "rollup"
+VERSION = "2.14.0"
+_ROOT_PACKAGE = "<LOCKVERSION>"
+_PACKAGE_STORE_NAME = "rollup@2.14.0"
 
 # Generated npm_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/pkg".format(link_root_name): "fsevents",
-        ":.aspect_rules_js/{}/rollup@2.14.0/pkg".format(link_root_name): "rollup",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/ref".format(link_root_name): "fsevents",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "rollup",
-        version = "2.14.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg": "rollup",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/ref": "fsevents",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg_pre_lc_lite": "rollup",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//<LOCKVERSION>:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
@@ -98,43 +64,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    link_packages = {
-        "<LOCKVERSION>": ["rollup"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["rollup"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "<LOCKVERSION>": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/e2e/pnpm_lockfiles/v60/snapshots/rollup_links_defs.bzl b/e2e/pnpm_lockfiles/v60/snapshots/rollup_links_defs.bzl
index 5fd4bbd..60ebee0 100644
--- a/e2e/pnpm_lockfiles/v60/snapshots/rollup_links_defs.bzl
+++ b/e2e/pnpm_lockfiles/v60/snapshots/rollup_links_defs.bzl
@@ -4,92 +4,58 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "rollup"
+VERSION = "2.14.0"
+_ROOT_PACKAGE = "<LOCKVERSION>"
+_PACKAGE_STORE_NAME = "rollup@2.14.0"
 
 # Generated npm_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/pkg".format(link_root_name): "fsevents",
-        ":.aspect_rules_js/{}/rollup@2.14.0/pkg".format(link_root_name): "rollup",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/ref".format(link_root_name): "fsevents",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "rollup",
-        version = "2.14.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg": "rollup",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/ref": "fsevents",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg_pre_lc_lite": "rollup",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//<LOCKVERSION>:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
@@ -98,43 +64,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    link_packages = {
-        "<LOCKVERSION>": ["rollup"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["rollup"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "<LOCKVERSION>": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/e2e/pnpm_lockfiles/v61/snapshots/rollup_links_defs.bzl b/e2e/pnpm_lockfiles/v61/snapshots/rollup_links_defs.bzl
index 5fd4bbd..60ebee0 100644
--- a/e2e/pnpm_lockfiles/v61/snapshots/rollup_links_defs.bzl
+++ b/e2e/pnpm_lockfiles/v61/snapshots/rollup_links_defs.bzl
@@ -4,92 +4,58 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "rollup"
+VERSION = "2.14.0"
+_ROOT_PACKAGE = "<LOCKVERSION>"
+_PACKAGE_STORE_NAME = "rollup@2.14.0"
 
 # Generated npm_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/pkg".format(link_root_name): "fsevents",
-        ":.aspect_rules_js/{}/rollup@2.14.0/pkg".format(link_root_name): "rollup",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/ref".format(link_root_name): "fsevents",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "rollup",
-        version = "2.14.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg": "rollup",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/ref": "fsevents",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg_pre_lc_lite": "rollup",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//<LOCKVERSION>:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
@@ -98,43 +64,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    link_packages = {
-        "<LOCKVERSION>": ["rollup"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["rollup"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "<LOCKVERSION>": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/e2e/pnpm_lockfiles/v90/snapshots/rollup_links_defs.bzl b/e2e/pnpm_lockfiles/v90/snapshots/rollup_links_defs.bzl
index 5fd4bbd..60ebee0 100644
--- a/e2e/pnpm_lockfiles/v90/snapshots/rollup_links_defs.bzl
+++ b/e2e/pnpm_lockfiles/v90/snapshots/rollup_links_defs.bzl
@@ -4,92 +4,58 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "rollup"
+VERSION = "2.14.0"
+_ROOT_PACKAGE = "<LOCKVERSION>"
+_PACKAGE_STORE_NAME = "rollup@2.14.0"
 
 # Generated npm_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/pkg".format(link_root_name): "fsevents",
-        ":.aspect_rules_js/{}/rollup@2.14.0/pkg".format(link_root_name): "rollup",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.3/ref".format(link_root_name): "fsevents",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "rollup",
-        version = "2.14.0",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg": "rollup",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/ref": "fsevents",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.3/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.14.0/pkg_pre_lc_lite": "rollup",
+        },
         dev = False,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
-        package = "rollup",
-        version = "2.14.0",
-        dev = False,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@aspect_rules_js~~npm~lock-<LOCKVERSION>__rollup__2.14.0//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/rollup@2.14.0".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//<LOCKVERSION>:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.14.0
@@ -98,43 +64,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = "<LOCKVERSION>"
-    link_packages = {
-        "<LOCKVERSION>": ["rollup"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package rollup@2.14.0. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["rollup"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "<LOCKVERSION>": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/npm/private/BUILD.bazel b/npm/private/BUILD.bazel
index 8bc3865..794a8d1 100644
--- a/npm/private/BUILD.bazel
+++ b/npm/private/BUILD.bazel
@@ -88,6 +88,9 @@
     name = "npm_import",
     srcs = ["npm_import.bzl"],
     deps = [
+        ":npm_link_package_store",
+        ":npm_package_internal",
+        ":npm_package_store_internal",
         ":starlark_codegen_utils",
         ":tar",
         ":utils",
diff --git a/npm/private/npm_import.bzl b/npm/private/npm_import.bzl
index ad91ec7..d85487c 100644
--- a/npm/private/npm_import.bzl
+++ b/npm/private/npm_import.bzl
@@ -31,6 +31,9 @@
     _git_reset = "reset",
 )
 load("//npm/private:tar.bzl", "detect_system_tar")
+load(":npm_link_package_store.bzl", "npm_link_package_store")
+load(":npm_package_internal.bzl", "npm_package_internal")
+load(":npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 load(":starlark_codegen_utils.bzl", "starlark_codegen_utils")
 load(":utils.bzl", "utils")
 
@@ -39,184 +42,260 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")\
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
 """
 
-_LINK_JS_PACKAGE_LIFECYCLE_LOADS_TMPL = """\
-load("@aspect_rules_js//js:defs.bzl", _js_run_binary = "js_run_binary")
+_LINK_JS_PACKAGE_TMPL = """\
+PACKAGE = "{package}"
+VERSION = "{version}"
+_ROOT_PACKAGE = "{root_package}"
+_PACKAGE_STORE_NAME = "{package_store_name}"
 
-# buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_package_internal.bzl", _npm_package_internal = "npm_package_internal")\
-"""
-
-_LINK_JS_PACKAGE_TMPL = """
 # Generated npm_package_store targets for npm package {package}@{version}
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {deps},
+        ref_deps = {ref_deps},
+        lc_deps = {lc_deps},
+        dev = {dev},
+        has_lifecycle_build_target = {has_lifecycle_build_target},
+        transitive_closure_pattern = {transitive_closure_pattern},
+        npm_package_target = "{npm_package_target}",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {lifecycle_hooks_env},
+        lifecycle_hooks_execution_requirements = {lifecycle_hooks_execution_requirements},
+        use_default_shell_env = {use_default_shell_env},
+        exclude_package_contents = {exclude_package_contents},
+    )
+"""
+
+# Invoked by generated npm_package_store targets for npm package {package}@{version}
+# buildifier: disable=function-docstring
+# buildifier: disable=unnamed-macro
+def npm_imported_package_store_internal(
+        link_root_name,
+        package,
+        version,
+        root_package,
+        deps,
+        ref_deps,
+        lc_deps,
+        dev,
+        has_lifecycle_build_target,
+        transitive_closure_pattern,
+        npm_package_target,
+        package_store_name,
+        lifecycle_hooks_env,
+        lifecycle_hooks_execution_requirements,
+        use_default_shell_env,
+        exclude_package_contents):
     bazel_package = native.package_name()
-    root_package = "{root_package}"
     is_root = bazel_package == root_package
     if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package {package}@{version}. This is neither the root package nor a link package of this package." % bazel_package
+        msg = "No store links in bazel package '{bazel_package}' for npm package npm package {package}@{version}. This is neither the root package nor a link package of this package.".format(
+            bazel_package = bazel_package,
+            package = package,
+            version = version,
+        )
         fail(msg)
 
-    deps = {deps}
-    ref_deps = {ref_deps}
+    deps = {k.format(link_root_name = link_root_name): v for k, v in deps.items()}
+    ref_deps = {k.format(link_root_name = link_root_name): v for k, v in ref_deps.items()}
+    lc_deps = {k.format(link_root_name = link_root_name): v for k, v in lc_deps.items()}
 
-    store_target_name = "{package_store_root}/{{}}/{package_store_name}".format(link_root_name)
+    store_target_name = "%s/%s/%s" % (utils.package_store_root, link_root_name, package_store_name)
 
     # reference target used to avoid circular deps
     _npm_package_store(
-        name = "{{}}/ref".format(store_target_name),
-        package = "{package}",
-        version = "{version}",
-        dev = {dev},
-        tags = ["manual"],{maybe_exclude_package_contents}
+        name = "{}/ref".format(store_target_name),
+        package = package,
+        version = version,
+        dev = dev,
+        tags = ["manual"],
+        exclude_package_contents = exclude_package_contents,
     )
 
     # post-lifecycle target with reference deps for use in terminal target with transitive closure
     _npm_package_store(
-        name = "{{}}/pkg".format(store_target_name),
-        src = "{{}}/pkg_lc".format(store_target_name) if {has_lifecycle_build_target} else "{npm_package_target}",
-        package = "{package}",
-        version = "{version}",
-        dev = {dev},
+        name = "{}/pkg".format(store_target_name),
+        src = "{}/pkg_lc".format(store_target_name) if has_lifecycle_build_target else npm_package_target,
+        package = package,
+        version = version,
+        dev = dev,
         deps = ref_deps,
-        tags = ["manual"],{maybe_exclude_package_contents}
+        tags = ["manual"],
+        exclude_package_contents = exclude_package_contents,
     )
 
     # package store target with transitive closure of all npm package dependencies
     _npm_package_store(
         name = store_target_name,
-        src = None if {transitive_closure_pattern} else "{npm_package_target}",
-        package = "{package}",
-        version = "{version}",
-        dev = {dev},
+        src = None if transitive_closure_pattern else npm_package_target,
+        package = package,
+        version = version,
+        dev = dev,
         deps = deps,
         visibility = ["//visibility:public"],
-        tags = ["manual"],{maybe_exclude_package_contents}
+        tags = ["manual"],
+        exclude_package_contents = exclude_package_contents,
     )
 
     # filegroup target that provides a single file which is
     # package directory for use in $(execpath) and $(rootpath)
     native.filegroup(
-        name = "{{}}/dir".format(store_target_name),
-        srcs = [":{{}}".format(store_target_name)],
-        output_group = "{package_directory_output_group}",
+        name = "{}/dir".format(store_target_name),
+        srcs = [":{}".format(store_target_name)],
+        output_group = utils.package_directory_output_group,
         visibility = ["//visibility:public"],
         tags = ["manual"],
     )
-"""
 
-_LINK_JS_PACKAGE_LIFECYCLE_TMPL = """\
-    lc_deps = {lc_deps}
+    if has_lifecycle_build_target:
+        # pre-lifecycle target with reference deps for use terminal pre-lifecycle target
+        _npm_package_store(
+            name = "{}/pkg_pre_lc_lite".format(store_target_name),
+            package = package,
+            version = version,
+            dev = dev,
+            deps = ref_deps,
+            tags = ["manual"],
+            exclude_package_contents = exclude_package_contents,
+        )
 
-    # pre-lifecycle target with reference deps for use terminal pre-lifecycle target
-    _npm_package_store(
-        name = "{{}}/pkg_pre_lc_lite".format(store_target_name),
-        package = "{package}",
-        version = "{version}",
-        dev = {dev},
-        deps = ref_deps,
-        tags = ["manual"],{maybe_exclude_package_contents}
-    )
+        # terminal pre-lifecycle target for use in lifecycle build target below
+        _npm_package_store(
+            name = "{}/pkg_pre_lc".format(store_target_name),
+            package = package,
+            version = version,
+            dev = dev,
+            deps = lc_deps,
+            tags = ["manual"],
+            exclude_package_contents = exclude_package_contents,
+        )
 
-    # terminal pre-lifecycle target for use in lifecycle build target below
-    _npm_package_store(
-        name = "{{}}/pkg_pre_lc".format(store_target_name),
-        package = "{package}",
-        version = "{version}",
-        dev = {dev},
-        deps = lc_deps,
-        tags = ["manual"],{maybe_exclude_package_contents}
-    )
+        # "node_modules/{package_store_root}/{package_store_name}/node_modules/{package}"
+        lifecycle_output_dir = "node_modules/{}/{}/node_modules/{}".format(utils.package_store_root, package_store_name, package)
 
-    # lifecycle build action
-    _js_run_binary(
-        name = "{{}}/lc".format(store_target_name),
-        srcs = [
-            "{npm_package_target}",
-            ":{{}}/pkg_pre_lc".format(store_target_name),
-        ],
-        # js_run_binary runs in the output dir; must add "../../../" because paths are relative to the exec root
-        args = [
-                   "{package}",
-                   "../../../$(execpath {npm_package_target})",
-                   "../../../$(@D)",
-               ] +
-               select({{
-                   Label("@aspect_rules_js//platforms/os:osx"): ["--platform=darwin"],
-                   Label("@aspect_rules_js//platforms/os:linux"): ["--platform=linux"],
-                   Label("@aspect_rules_js//platforms/os:windows"): ["--platform=win32"],
-                   "//conditions:default": [],
-               }}) +
-               select({{
-                   Label("@aspect_rules_js//platforms/cpu:arm64"): ["--arch=arm64"],
-                   Label("@aspect_rules_js//platforms/cpu:x86_64"): ["--arch=x64"],
-                   "//conditions:default": [],
-               }}) +
-               select({{
-                   Label("@aspect_rules_js//platforms/libc:glibc"): ["--libc=glibc"],
-                   Label("@aspect_rules_js//platforms/libc:musl"): ["--libc=musl"],
-                   "//conditions:default": [],
-               }}),
-        copy_srcs_to_bin = False,
-        tool = Label("@aspect_rules_js//npm/private/lifecycle:lifecycle-hooks"),
-        out_dirs = ["{lifecycle_output_dir}"],
+        # lifecycle build action
+        _js_run_binary(
+            name = "{}/lc".format(store_target_name),
+            srcs = [
+                npm_package_target,
+                ":{}/pkg_pre_lc".format(store_target_name),
+            ],
+            # js_run_binary runs in the output dir; must add "../../../" because paths are relative to the exec root
+            args = [
+                       package,
+                       "../../../$(execpath {})".format(npm_package_target),
+                       "../../../$(@D)",
+                   ] +
+                   select({
+                       Label("@aspect_rules_js//platforms/os:osx"): ["--platform=darwin"],
+                       Label("@aspect_rules_js//platforms/os:linux"): ["--platform=linux"],
+                       Label("@aspect_rules_js//platforms/os:windows"): ["--platform=win32"],
+                       "//conditions:default": [],
+                   }) +
+                   select({
+                       Label("@aspect_rules_js//platforms/cpu:arm64"): ["--arch=arm64"],
+                       Label("@aspect_rules_js//platforms/cpu:x86_64"): ["--arch=x64"],
+                       "//conditions:default": [],
+                   }) +
+                   select({
+                       Label("@aspect_rules_js//platforms/libc:glibc"): ["--libc=glibc"],
+                       Label("@aspect_rules_js//platforms/libc:musl"): ["--libc=musl"],
+                       "//conditions:default": [],
+                   }),
+            copy_srcs_to_bin = False,
+            tool = Label("@aspect_rules_js//npm/private/lifecycle:lifecycle-hooks"),
+            out_dirs = [lifecycle_output_dir],
+            tags = ["manual"],
+            execution_requirements = lifecycle_hooks_execution_requirements,
+            mnemonic = "NpmLifecycleHook",
+            progress_message = "Running lifecycle hooks on npm package %s@%s}" % (package, version),
+            env = lifecycle_hooks_env,
+            use_default_shell_env = use_default_shell_env,
+        )
+
+        # post-lifecycle npm_package
+        npm_package_internal(
+            name = "{}/pkg_lc".format(store_target_name),
+            src = ":{}/lc".format(store_target_name),
+            package = "{package}",
+            version = "{version}",
+            tags = ["manual"],
+        )
+
+def npm_link_imported_package_store_internal(
+        name,
+        link_root_name,
+        link_alias,
+        root_package,
+        link_visibility,
+        bins,
+        package_store_name,
+        public_visibility):
+    store_target_name = "%s/%s/%s" % (utils.package_store_root, link_root_name, package_store_name)
+
+    # terminal package store target to link
+    npm_link_package_store(
+        name = name,
+        package = link_alias,
+        src = "//%s:%s" % (root_package, store_target_name),
+        visibility = link_visibility,
         tags = ["manual"],
-        execution_requirements = {lifecycle_hooks_execution_requirements},
-        mnemonic = "NpmLifecycleHook",
-        progress_message = "Running lifecycle hooks on npm package {package}@{version}",
-        env = {lifecycle_hooks_env},
-        use_default_shell_env = {use_default_shell_env},
+        bins = bins,
     )
 
-    # post-lifecycle npm_package
-    _npm_package_internal(
-        name = "{{}}/pkg_lc".format(store_target_name),
-        src = ":{{}}/lc".format(store_target_name),
-        package = "{package}",
-        version = "{version}",
+    # filegroup target that provides a single file which is
+    # package directory for use in $(execpath) and $(rootpath)
+    native.filegroup(
+        name = "{}/dir".format(name),
+        srcs = [":" + name],
+        output_group = utils.package_directory_output_group,
+        visibility = link_visibility,
         tags = ["manual"],
     )
-"""
+
+    return [":{}".format(name)] if public_visibility else []
 
 _LINK_JS_PACKAGE_LINK_IMPORTED_STORE_TMPL = """\
 # Generated npm_package_store and npm_link_package_store targets for npm package {package}@{version}
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = "{package_store_root}/{{}}/{package_store_name}".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//{root_package}:{{}}".format(store_target_name),
-        visibility = {link_visibility},
-        tags = ["manual"],{maybe_bins}
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{{}}/dir".format(name),
-        srcs = [":{{}}".format(name)],
-        output_group = "{package_directory_output_group}",
-        visibility = {link_visibility},
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = {link_visibility},
+        bins = {bins},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = {public_visibility},
     )
 """
 
-_LINK_JS_PACKAGE_LINK_IMPORTED_PKG_TMPL = """\
-# Generated npm_package_store and npm_link_package_store targets for npm package {package}@{version}
+# Invoked by generated npm_link_imported_package_store targets for npm package {package}@{version}
 # buildifier: disable=function-docstring
-def npm_link_imported_package(
-        name = "node_modules",
-        link = {link_default},
+def npm_link_imported_package_internal(
+        name,
+        package,
+        version,
+        root_package,
+        link,
+        link_packages,
+        public_visibility,
+        npm_link_imported_package_store_macro,
+        npm_imported_package_store_macro,
         fail_if_no_link = True):
     bazel_package = native.package_name()
-    root_package = "{root_package}"
-    link_packages = {link_packages}
 
     if link_packages and link != None:
         fail("link attribute cannot be specified when link_packages are set")
@@ -225,23 +304,31 @@
     is_root = bazel_package == root_package
 
     if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package {package}@{version}. This is neither the root package nor a link package of this package." % bazel_package
+        msg = "Nothing to link in bazel package '{bazel_package}' for npm package npm package {package}@{version}. This is neither the root package nor a link package of this package.".format(
+            bazel_package = bazel_package,
+            package = package,
+            version = version,
+        )
         fail(msg)
 
     link_targets = []
-    scoped_targets = {{}}
+    scoped_targets = {}
 
     if is_link:
         link_aliases = []
         if bazel_package in link_packages:
             link_aliases = link_packages[bazel_package]
         if not link_aliases:
-            link_aliases = ["{package}"]
+            link_aliases = [package]
         for link_alias in link_aliases:
-            link_target_name = "{{}}/{{}}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if {public_visibility}:
-                link_targets.append(":{{}}".format(link_target_name))
+            link_target_name = "{}/{}".format(name, link_alias)
+            npm_link_imported_package_store_macro(
+                name = link_target_name,
+                link_root_name = name,
+                link_alias = link_alias,
+            )
+            if public_visibility:
+                link_targets.append(":" + link_target_name)
                 link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
                 if link_scope:
                     if link_scope not in scoped_targets:
@@ -249,9 +336,29 @@
                     scoped_targets[link_scope].append(link_target_name)
 
     if is_root:
-        npm_imported_package_store(name)
+        npm_imported_package_store_macro(name)
 
     return (link_targets, scoped_targets)
+
+_LINK_JS_PACKAGE_LINK_IMPORTED_PKG_TMPL = """\
+# Generated npm_package_store and npm_link_package_store targets for npm package {package}@{version}
+# buildifier: disable=function-docstring
+def npm_link_imported_package(
+        name = "node_modules",
+        link = {link_default},
+        fail_if_no_link = True):
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {link_packages},
+        public_visibility = {public_visibility},
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
 """
 
 def bin_internal(name, link_workspace_and_package, link_root_name, package_store_name, bin_path, bin_mnemonic, **kwargs):
@@ -643,9 +750,9 @@
     for (dep_name, dep_version) in rctx.attr.deps.items():
         dep_package_store_name = utils.package_store_name(dep_name, dep_version)
         if dep_version.startswith("link:") or dep_version.startswith("file:"):
-            dep_store_target = """"//{root_package}:{package_store_root}/{{}}/{package_store_name}".format(link_root_name)"""
+            dep_store_target = '"//{root_package}:{package_store_root}/{{link_root_name}}/{package_store_name}"'
         else:
-            dep_store_target = """":{package_store_root}/{{}}/{package_store_name}/ref".format(link_root_name)"""
+            dep_store_target = '":{package_store_root}/{{link_root_name}}/{package_store_name}/ref"'
         dep_store_target = dep_store_target.format(
             root_package = rctx.attr.root_package,
             package_store_name = dep_package_store_name,
@@ -663,16 +770,16 @@
         for (dep_name, dep_versions) in rctx.attr.transitive_closure.items():
             for dep_version in dep_versions:
                 if dep_version.startswith("link:") or dep_version.startswith("file:"):
-                    dep_store_target = """"//{root_package}:{package_store_root}/{{}}/{package_store_name}".format(link_root_name)"""
+                    dep_store_target = '"//{root_package}:{package_store_root}/{{link_root_name}}/{package_store_name}"'
                     lc_dep_store_target = dep_store_target
                 else:
-                    dep_store_target = """":{package_store_root}/{{}}/{package_store_name}/pkg".format(link_root_name)"""
+                    dep_store_target = '":{package_store_root}/{{link_root_name}}/{package_store_name}/pkg"'
                     lc_dep_store_target = dep_store_target
                     if dep_name == rctx.attr.package and dep_version == rctx.attr.version:
                         # special case for lifecycle transitive closure deps; do not depend on
                         # the __pkg of this package as that will be the output directory
                         # of the lifecycle action
-                        lc_dep_store_target = """":{package_store_root}/{{}}/{package_store_name}/pkg_pre_lc_lite".format(link_root_name)"""
+                        lc_dep_store_target = '":{package_store_root}/{{link_root_name}}/{package_store_name}/pkg_pre_lc_lite"'
 
                 dep_package_store_name = utils.package_store_name(dep_name, dep_version)
 
@@ -696,7 +803,7 @@
                 deps[dep_store_target].append(dep_name)
     else:
         for (dep_name, dep_version) in rctx.attr.deps.items():
-            dep_store_target = """":{package_store_root}/{{}}/{package_store_name}".format(link_root_name)""".format(
+            dep_store_target = '":{package_store_root}/{{link_root_name}}/{package_store_name}"'.format(
                 package_store_name = utils.package_store_name(dep_name, dep_version),
                 package_store_root = utils.package_store_root,
             )
@@ -711,9 +818,6 @@
 
     package_store_name = utils.package_store_name(rctx.attr.package, rctx.attr.version)
 
-    # "node_modules/{package_store_root}/{package_store_name}/node_modules/{package}"
-    lifecycle_output_dir = "node_modules/{}/{}/node_modules/{}".format(utils.package_store_root, package_store_name, rctx.attr.package)
-
     # strip _links post-fix to get the repository name of the npm sources
     npm_import_sources_repo_name = rctx.name[:-len(utils.links_repo_suffix)]
 
@@ -724,9 +828,19 @@
             npm_import_sources_repo_name,
         )
 
-    link_packages = {}
+    link_packages = "{\n"
+    indent = " " * 12
     for package, link_aliases in rctx.attr.link_packages.items():
-        link_packages[package] = link_aliases or [rctx.attr.package]
+        if link_aliases and link_aliases != [rctx.attr.package]:
+            link_packages += indent + '"{package}": {link_aliases},\n'.format(
+                package = package,
+                link_aliases = repr(link_aliases),
+            )
+        else:
+            link_packages += indent + '"{package}": [PACKAGE],\n'.format(
+                package = package,
+            )
+    link_packages += " " * 8 + "}"
 
     # collapse link aliases lists into comma separated strings
     for dep in deps.keys():
@@ -749,52 +863,38 @@
     for ec in rctx.attr.lifecycle_hooks_execution_requirements:
         lifecycle_hooks_execution_requirements[ec] = "1"
 
-    maybe_bins = ("""
-        bins = %s,""" % starlark_codegen_utils.to_dict_attr(rctx.attr.bins, 3)) if len(rctx.attr.bins) > 0 else ""
+    bins = starlark_codegen_utils.to_dict_attr(rctx.attr.bins, 2) if len(rctx.attr.bins) > 0 else "{}"
 
     public_visibility = ("//visibility:public" in rctx.attr.package_visibility)
 
-    maybe_exclude_package_contents = ""
-    if rctx.attr.exclude_package_contents == []:
-        maybe_exclude_package_contents = ""
-    elif rctx.attr.exclude_package_contents != None:
-        maybe_exclude_package_contents = "\n        exclude_package_contents = " + starlark_codegen_utils.to_list_attr(rctx.attr.exclude_package_contents) + ","
-
     npm_link_pkg_bzl_vars = dict(
-        deps = starlark_codegen_utils.to_dict_attr(deps, 1, quote_key = False),
+        deps = starlark_codegen_utils.to_dict_attr(deps, 2, quote_key = False),
         link_default = "None" if rctx.attr.link_packages else "True",
         npm_package_target = npm_package_target,
-        lc_deps = starlark_codegen_utils.to_dict_attr(lc_deps, 1, quote_key = False),
+        lc_deps = starlark_codegen_utils.to_dict_attr(lc_deps, 2, quote_key = False),
         has_lifecycle_build_target = str(rctx.attr.lifecycle_build_target),
         lifecycle_hooks_execution_requirements = starlark_codegen_utils.to_dict_attr(lifecycle_hooks_execution_requirements, 2),
         lifecycle_hooks_env = starlark_codegen_utils.to_dict_attr(lifecycle_hooks_env),
-        lifecycle_output_dir = lifecycle_output_dir,
-        npm_link_package_bzl = "@%s//:%s" % (rctx.name, _DEFS_BZL_FILENAME),
-        link_packages = starlark_codegen_utils.to_dict_attr(link_packages, 1, quote_value = False),
+        link_packages = link_packages,
         link_visibility = rctx.attr.package_visibility,
         public_visibility = str(public_visibility),
         package = rctx.attr.package,
-        package_directory_output_group = utils.package_directory_output_group,
-        rctx_name = rctx.name,
-        ref_deps = starlark_codegen_utils.to_dict_attr(ref_deps, 1, quote_key = False),
+        ref_deps = starlark_codegen_utils.to_dict_attr(ref_deps, 2, quote_key = False),
         root_package = rctx.attr.root_package,
         transitive_closure_pattern = str(transitive_closure_pattern),
         version = rctx.attr.version,
         package_store_name = package_store_name,
-        package_store_root = utils.package_store_root,
-        maybe_bins = maybe_bins,
+        bins = bins,
         dev = rctx.attr.dev,
         use_default_shell_env = rctx.attr.lifecycle_hooks_use_default_shell_env,
-        maybe_exclude_package_contents = maybe_exclude_package_contents,
+        exclude_package_contents = starlark_codegen_utils.to_list_attr(rctx.attr.exclude_package_contents),
     )
 
     npm_link_package_bzl = [
         tmpl.format(**npm_link_pkg_bzl_vars)
         for tmpl in [
             _LINK_JS_PACKAGE_LOADS_TMPL,
-            _LINK_JS_PACKAGE_LIFECYCLE_LOADS_TMPL if rctx.attr.lifecycle_build_target else None,
             _LINK_JS_PACKAGE_TMPL,
-            _LINK_JS_PACKAGE_LIFECYCLE_TMPL if rctx.attr.lifecycle_build_target else None,
             _LINK_JS_PACKAGE_LINK_IMPORTED_STORE_TMPL,
             _LINK_JS_PACKAGE_LINK_IMPORTED_PKG_TMPL,
         ]
diff --git a/npm/private/test/snapshots/fsevents_links_defs.bzl b/npm/private/test/snapshots/fsevents_links_defs.bzl
index b1fade3..725af34 100644
--- a/npm/private/test/snapshots/fsevents_links_defs.bzl
+++ b/npm/private/test/snapshots/fsevents_links_defs.bzl
@@ -4,168 +4,56 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
-load("@aspect_rules_js//js:defs.bzl", _js_run_binary = "js_run_binary")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
 
-# buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_package_internal.bzl", _npm_package_internal = "npm_package_internal")
+PACKAGE = "fsevents"
+VERSION = "2.3.2"
+_ROOT_PACKAGE = ""
+_PACKAGE_STORE_NAME = "fsevents@2.3.2"
 
 # Generated npm_package_store targets for npm package fsevents@2.3.2
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = ""
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package fsevents@2.3.2. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.2/pkg".format(link_root_name): "fsevents",
-    }
-    ref_deps = {}
-
-    store_target_name = ".aspect_rules_js/{}/fsevents@2.3.2".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "fsevents",
-        version = "2.3.2",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.2/pkg": "fsevents",
+        },
+        ref_deps = {},
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.2/pkg_pre_lc_lite": "fsevents",
+        },
         dev = True,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if True else "@@_main~npm~npm__fsevents__2.3.2//:pkg",
-        package = "fsevents",
-        version = "2.3.2",
-        dev = True,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@_main~npm~npm__fsevents__2.3.2//:pkg",
-        package = "fsevents",
-        version = "2.3.2",
-        dev = True,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    lc_deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.2/pkg_pre_lc_lite".format(link_root_name): "fsevents",
-    }
-
-    # pre-lifecycle target with reference deps for use terminal pre-lifecycle target
-    _npm_package_store(
-        name = "{}/pkg_pre_lc_lite".format(store_target_name),
-        package = "fsevents",
-        version = "2.3.2",
-        dev = True,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # terminal pre-lifecycle target for use in lifecycle build target below
-    _npm_package_store(
-        name = "{}/pkg_pre_lc".format(store_target_name),
-        package = "fsevents",
-        version = "2.3.2",
-        dev = True,
-        deps = lc_deps,
-        tags = ["manual"],
-    )
-
-    # lifecycle build action
-    _js_run_binary(
-        name = "{}/lc".format(store_target_name),
-        srcs = [
-            "@@_main~npm~npm__fsevents__2.3.2//:pkg",
-            ":{}/pkg_pre_lc".format(store_target_name),
-        ],
-        # js_run_binary runs in the output dir; must add "../../../" because paths are relative to the exec root
-        args = [
-                   "fsevents",
-                   "../../../$(execpath @@_main~npm~npm__fsevents__2.3.2//:pkg)",
-                   "../../../$(@D)",
-               ] +
-               select({
-                   Label("@aspect_rules_js//platforms/os:osx"): ["--platform=darwin"],
-                   Label("@aspect_rules_js//platforms/os:linux"): ["--platform=linux"],
-                   Label("@aspect_rules_js//platforms/os:windows"): ["--platform=win32"],
-                   "//conditions:default": [],
-               }) +
-               select({
-                   Label("@aspect_rules_js//platforms/cpu:arm64"): ["--arch=arm64"],
-                   Label("@aspect_rules_js//platforms/cpu:x86_64"): ["--arch=x64"],
-                   "//conditions:default": [],
-               }) +
-               select({
-                   Label("@aspect_rules_js//platforms/libc:glibc"): ["--libc=glibc"],
-                   Label("@aspect_rules_js//platforms/libc:musl"): ["--libc=musl"],
-                   "//conditions:default": [],
-               }),
-        copy_srcs_to_bin = False,
-        tool = Label("@aspect_rules_js//npm/private/lifecycle:lifecycle-hooks"),
-        out_dirs = ["node_modules/.aspect_rules_js/fsevents@2.3.2/node_modules/fsevents"],
-        tags = ["manual"],
-        execution_requirements = {
+        has_lifecycle_build_target = True,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@_main~npm~npm__fsevents__2.3.2//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {
             "no-sandbox": "1",
         },
-        mnemonic = "NpmLifecycleHook",
-        progress_message = "Running lifecycle hooks on npm package fsevents@2.3.2",
-        env = {},
         use_default_shell_env = False,
-    )
-
-    # post-lifecycle npm_package
-    _npm_package_internal(
-        name = "{}/pkg_lc".format(store_target_name),
-        src = ":{}/lc".format(store_target_name),
-        package = "fsevents",
-        version = "2.3.2",
-        tags = ["manual"],
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package fsevents@2.3.2
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/fsevents@2.3.2".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package fsevents@2.3.2
@@ -174,41 +62,16 @@
         name = "node_modules",
         link = True,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = ""
-    link_packages = {}
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package fsevents@2.3.2. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["fsevents"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/npm/private/test/snapshots/rollup_links_defs.bzl b/npm/private/test/snapshots/rollup_links_defs.bzl
index d85c503..0981135 100644
--- a/npm/private/test/snapshots/rollup_links_defs.bzl
+++ b/npm/private/test/snapshots/rollup_links_defs.bzl
@@ -4,92 +4,58 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "rollup"
+VERSION = "2.70.2"
+_ROOT_PACKAGE = ""
+_PACKAGE_STORE_NAME = "rollup@2.70.2"
 
 # Generated npm_package_store targets for npm package rollup@2.70.2
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = ""
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package rollup@2.70.2. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.2/pkg".format(link_root_name): "fsevents",
-        ":.aspect_rules_js/{}/rollup@2.70.2/pkg".format(link_root_name): "rollup",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/fsevents@2.3.2/ref".format(link_root_name): "fsevents",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/rollup@2.70.2".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "rollup",
-        version = "2.70.2",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.2/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.70.2/pkg": "rollup",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.2/ref": "fsevents",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/fsevents@2.3.2/pkg": "fsevents",
+            ":.aspect_rules_js/{link_root_name}/rollup@2.70.2/pkg_pre_lc_lite": "rollup",
+        },
         dev = True,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@_main~npm~npm__rollup__2.70.2//:pkg",
-        package = "rollup",
-        version = "2.70.2",
-        dev = True,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@_main~npm~npm__rollup__2.70.2//:pkg",
-        package = "rollup",
-        version = "2.70.2",
-        dev = True,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@_main~npm~npm__rollup__2.70.2//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.70.2
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/rollup@2.70.2".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//:{}".format(store_target_name),
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:public"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = True,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package rollup@2.70.2
@@ -98,43 +64,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = ""
-    link_packages = {
-        "examples/npm_deps": ["rollup"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package rollup@2.70.2. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["rollup"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if True:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "examples/npm_deps": [PACKAGE],
+        },
+        public_visibility = True,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )
diff --git a/npm/private/test/snapshots/unused_links_defs.bzl b/npm/private/test/snapshots/unused_links_defs.bzl
index 4c70c55..d029334 100644
--- a/npm/private/test/snapshots/unused_links_defs.bzl
+++ b/npm/private/test/snapshots/unused_links_defs.bzl
@@ -4,96 +4,65 @@
 load("@aspect_rules_js//npm/private:npm_package_store_internal.bzl", _npm_package_store = "npm_package_store_internal")
 
 # buildifier: disable=bzl-visibility
-load("@aspect_rules_js//npm/private:npm_link_package_store.bzl", _npm_link_package_store = "npm_link_package_store")
+load("@aspect_rules_js//npm/private:npm_import.bzl",
+    _npm_imported_package_store = "npm_imported_package_store_internal",
+    _npm_link_imported_package = "npm_link_imported_package_internal",
+    _npm_link_imported_package_store = "npm_link_imported_package_store_internal")
+
+PACKAGE = "unused"
+VERSION = "0.2.2"
+_ROOT_PACKAGE = ""
+_PACKAGE_STORE_NAME = "unused@0.2.2"
 
 # Generated npm_package_store targets for npm package unused@0.2.2
 # buildifier: disable=function-docstring
 def npm_imported_package_store(link_root_name):
-    bazel_package = native.package_name()
-    root_package = ""
-    is_root = bazel_package == root_package
-    if not is_root:
-        msg = "No store links in bazel package '%s' for npm package npm package unused@0.2.2. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    deps = {
-        ":.aspect_rules_js/{}/esprima@1.0.0/pkg".format(link_root_name): "esprima",
-        ":.aspect_rules_js/{}/minimist@0.0.10/pkg".format(link_root_name): "minimist",
-        ":.aspect_rules_js/{}/optimist@0.6.0/pkg".format(link_root_name): "optimist",
-        ":.aspect_rules_js/{}/unused@0.2.2/pkg".format(link_root_name): "unused",
-        ":.aspect_rules_js/{}/wordwrap@0.0.3/pkg".format(link_root_name): "wordwrap",
-    }
-    ref_deps = {
-        ":.aspect_rules_js/{}/esprima@1.0.0/ref".format(link_root_name): "esprima",
-        ":.aspect_rules_js/{}/optimist@0.6.0/ref".format(link_root_name): "optimist",
-    }
-
-    store_target_name = ".aspect_rules_js/{}/unused@0.2.2".format(link_root_name)
-
-    # reference target used to avoid circular deps
-    _npm_package_store(
-        name = "{}/ref".format(store_target_name),
-        package = "unused",
-        version = "0.2.2",
+    _npm_imported_package_store(
+        link_root_name = link_root_name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        deps = {
+            ":.aspect_rules_js/{link_root_name}/esprima@1.0.0/pkg": "esprima",
+            ":.aspect_rules_js/{link_root_name}/minimist@0.0.10/pkg": "minimist",
+            ":.aspect_rules_js/{link_root_name}/optimist@0.6.0/pkg": "optimist",
+            ":.aspect_rules_js/{link_root_name}/unused@0.2.2/pkg": "unused",
+            ":.aspect_rules_js/{link_root_name}/wordwrap@0.0.3/pkg": "wordwrap",
+        },
+        ref_deps = {
+            ":.aspect_rules_js/{link_root_name}/esprima@1.0.0/ref": "esprima",
+            ":.aspect_rules_js/{link_root_name}/optimist@0.6.0/ref": "optimist",
+        },
+        lc_deps = {
+            ":.aspect_rules_js/{link_root_name}/esprima@1.0.0/pkg": "esprima",
+            ":.aspect_rules_js/{link_root_name}/minimist@0.0.10/pkg": "minimist",
+            ":.aspect_rules_js/{link_root_name}/optimist@0.6.0/pkg": "optimist",
+            ":.aspect_rules_js/{link_root_name}/unused@0.2.2/pkg_pre_lc_lite": "unused",
+            ":.aspect_rules_js/{link_root_name}/wordwrap@0.0.3/pkg": "wordwrap",
+        },
         dev = True,
-        tags = ["manual"],
-    )
-
-    # post-lifecycle target with reference deps for use in terminal target with transitive closure
-    _npm_package_store(
-        name = "{}/pkg".format(store_target_name),
-        src = "{}/pkg_lc".format(store_target_name) if False else "@@_main~npm~npm__unused__0.2.2//:pkg",
-        package = "unused",
-        version = "0.2.2",
-        dev = True,
-        deps = ref_deps,
-        tags = ["manual"],
-    )
-
-    # package store target with transitive closure of all npm package dependencies
-    _npm_package_store(
-        name = store_target_name,
-        src = None if True else "@@_main~npm~npm__unused__0.2.2//:pkg",
-        package = "unused",
-        version = "0.2.2",
-        dev = True,
-        deps = deps,
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(store_target_name),
-        srcs = [":{}".format(store_target_name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:public"],
-        tags = ["manual"],
+        has_lifecycle_build_target = False,
+        transitive_closure_pattern = True,
+        npm_package_target = "@@_main~npm~npm__unused__0.2.2//:pkg",
+        package_store_name = _PACKAGE_STORE_NAME,
+        lifecycle_hooks_env = {},
+        lifecycle_hooks_execution_requirements = {},
+        use_default_shell_env = False,
+        exclude_package_contents = [],
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package unused@0.2.2
 # buildifier: disable=function-docstring
 def npm_link_imported_package_store(name, link_root_name, link_alias):
-    store_target_name = ".aspect_rules_js/{}/unused@0.2.2".format(link_root_name)
-
-    # terminal package store target to link
-    _npm_link_package_store(
-        name = name,
-        package = link_alias,
-        src = "//:{}".format(store_target_name),
-        visibility = ["//visibility:private"],
-        tags = ["manual"],
-    )
-
-    # filegroup target that provides a single file which is
-    # package directory for use in $(execpath) and $(rootpath)
-    native.filegroup(
-        name = "{}/dir".format(name),
-        srcs = [":{}".format(name)],
-        output_group = "package_directory",
-        visibility = ["//visibility:private"],
-        tags = ["manual"],
+    return _npm_link_imported_package_store(
+        name,
+        link_root_name,
+        link_alias,
+        root_package = _ROOT_PACKAGE,
+        link_visibility = ["//visibility:private"],
+        bins = {},
+        package_store_name = _PACKAGE_STORE_NAME,
+        public_visibility = False,
     )
 
 # Generated npm_package_store and npm_link_package_store targets for npm package unused@0.2.2
@@ -102,43 +71,17 @@
         name = "node_modules",
         link = None,
         fail_if_no_link = True):
-    bazel_package = native.package_name()
-    root_package = ""
-    link_packages = {
-        "npm/private/test": ["unused"],
-    }
-
-    if link_packages and link != None:
-        fail("link attribute cannot be specified when link_packages are set")
-
-    is_link = (link == True) or (link == None and bazel_package in link_packages)
-    is_root = bazel_package == root_package
-
-    if fail_if_no_link and not is_root and not link:
-        msg = "Nothing to link in bazel package '%s' for npm package npm package unused@0.2.2. This is neither the root package nor a link package of this package." % bazel_package
-        fail(msg)
-
-    link_targets = []
-    scoped_targets = {}
-
-    if is_link:
-        link_aliases = []
-        if bazel_package in link_packages:
-            link_aliases = link_packages[bazel_package]
-        if not link_aliases:
-            link_aliases = ["unused"]
-        for link_alias in link_aliases:
-            link_target_name = "{}/{}".format(name, link_alias)
-            npm_link_imported_package_store(name = link_target_name, link_root_name = name, link_alias = link_alias)
-            if False:
-                link_targets.append(":{}".format(link_target_name))
-                link_scope = link_alias[:link_alias.find("/", 1)] if link_alias[0] == "@" else None
-                if link_scope:
-                    if link_scope not in scoped_targets:
-                        scoped_targets[link_scope] = []
-                    scoped_targets[link_scope].append(link_target_name)
-
-    if is_root:
-        npm_imported_package_store(name)
-
-    return (link_targets, scoped_targets)
+    return _npm_link_imported_package(
+        name,
+        package = PACKAGE,
+        version = VERSION,
+        root_package = _ROOT_PACKAGE,
+        link = link,
+        link_packages = {
+            "npm/private/test": [PACKAGE],
+        },
+        public_visibility = False,
+        npm_link_imported_package_store_macro = npm_link_imported_package_store,
+        npm_imported_package_store_macro = npm_imported_package_store,
+        fail_if_no_link = fail_if_no_link,
+    )