1+ load ("@aspect_rules_js//js:providers.bzl" , "JsInfo" )
2+
13def _extract_api_to_json (ctx ):
24 """Implementation of the extract_api_to_json rule"""
35
@@ -35,11 +37,43 @@ def _extract_api_to_json(ctx):
3537 # specifying them
3638 # https://github.com/bazelbuild/rules_nodejs/blob/5.x/internal/linker/link_node_modules.bzl#L236
3739 path_map = {}
38- for target , path in ctx .attr .import_map .items ():
40+ import_map_files = []
41+ for path , target in ctx .attr .import_map .items ():
3942 files = target .files .to_list ()
40- if len (files ) != 1 :
41- fail ("Expected a single file in import_map target %s" % target .label )
42- path_map [path ] = files [0 ].path
43+
44+ # Include transitive declarations if available in JsInfo
45+ if JsInfo in target :
46+ files .extend (target [JsInfo ].transitive_types .to_list ())
47+
48+ import_map_files .extend (files )
49+ if len (files ) == 1 :
50+ path_map [path ] = files [0 ].path
51+ else :
52+ found_path = None
53+ for f in files :
54+ if f .path .endswith ("/node_modules/" + path ):
55+ found_path = f .path
56+ break
57+
58+ # Handle @angular package subentries
59+ if path .startswith ("@angular/" ):
60+ parts = path .split ("/" )
61+ if len (parts ) > 2 :
62+ pkg_name = "/" .join (parts [:2 ])
63+ if f .path .endswith ("/node_modules/" + pkg_name ):
64+ subentry = parts [- 1 ]
65+ found_path = f .path + "/types/" + subentry + ".d.ts"
66+ break
67+
68+ if not found_path :
69+ candidates = [f for f in files if f .path .endswith ("/index.d.ts" )]
70+ sorted_candidates = sorted (candidates , key = lambda f : len (f .path ))
71+ found_path = sorted_candidates [0 ].path
72+
73+ if found_path :
74+ path_map [path ] = found_path
75+ else :
76+ fail ("Expected a single file in import_map target %s, but found %s. Could not determine entry point. Files: %s" % (target .label , len (files ), [f .path for f in files ]))
4377 args .add (json .encode (path_map ))
4478
4579 # Pass the set of (optional) extra entries
@@ -48,7 +82,7 @@ def _extract_api_to_json(ctx):
4882 # Define an action that runs the nodejs_binary executable. This is
4983 # the main thing that this rule does.
5084 ctx .actions .run (
51- inputs = depset (ctx .files .srcs + ctx .files .extra_entries ),
85+ inputs = depset (ctx .files .srcs + ctx .files .extra_entries + import_map_files ),
5286 executable = ctx .executable ._extract_api_to_json ,
5387 outputs = [json_output ],
5488 arguments = [args ],
@@ -86,7 +120,7 @@ extract_api_to_json = rule(
86120 "private_modules" : attr .string_list (
87121 doc = """List of private modules that should not be included in the API symbol linking""" ,
88122 ),
89- "import_map" : attr .label_keyed_string_dict (
123+ "import_map" : attr .string_keyed_label_dict (
90124 doc = """Map of import path to the index.ts file for that import""" ,
91125 allow_files = True ,
92126 ),
0 commit comments