What you want is a source-to-source program transformation system (PTS).
Such tools parse source code into ASTs, offer you the ability to transform those ASTs into other ASTs with surface-syntax patterns, and then spit out the source code for the correspondingly revised AST. If you transform from ASTs in one language to ASTs in another you get what you are calling a transpiler (not my favorite term; PTS was just fine).
Source to source transformation syntax varies, but in essence you write something like this using the surface (actual) language syntax of the source and target languages:
if you see *this*, replace it by *that* if some_condition(*this*)
The this and that element are patterns expressed in the language syntax; The optional conditional ("semantic constraint") allows the tool to take into account context information (such as symbol properties, etc.) Often it takes several or many rules to accomplish a complex transformation; the rules can usually be sequenced to achieve a compound effect of interest. The expression of the rulles and their sequencing the is "scripting" part of interest to OP.
You need to either get one that will accept new language definitions (the really general ones will) and define JavaScript to it, or get one that already has a JavaScript parser available and simply use that.
One of these genera, PTS is our DMS Software Reengineering Toolkit. It has an available Javascript front end.
OP's renaming problem can be specified as as a DMS Rewrite Rule as follows:
rule rename_controller(): IDENTIFIER
"controller" -> "getController";
The quote marks are meta quotes used to distinguish the syntax of the pattern language, from the syntax of the source/target langauges, which is written inside the meta quotes.
To rename all the API calls, OP would need rules for each unique API entry.
While easy to write, this is rather heavyhanded; any identifier with that name in the files processed by the will be so-renamed. That may rename "controller" in scopes that OP does not intend. If there is no danger of multiple declarations with the same name then this will be safe to execute using DMS's "apply rules everywhere" built-in tactic as a command-line scriptable task.
(It might be easier to rename the identifiers used in OP's code to the API identifiers; it is likely easier to avoid name collisions in code he writes than name collisions in the source files the APIs he did not write).
To do this right, OP has to somehow qualify which declaration of "controller" he wants renamed. That that he will have to define a custom constraint that checks he is renaming the "right" one, something like:
rule rename_controller(i:IDENTIFIER): IDENTIFIER
"\i" -> "getController"
if (match(i,"controller") & declaration_at_line(i,1219);
Here we we match any identifier with the intention of obtaining access to the AST node in which it is found (\i inside surface syntax text, i outside that text.). The match predicate is built-into DMS already; it is used to insist we found the right name. The declaration_at_line predicate is used to check that the matched AST node corresponds to one with the same name declared at a specific place in the file. This requires what amounts to a scoped name lookup that follows ECMAScript rules, so some custom work is required. (At present, this DMS front end does not provide that; other DMS front ends for other languages sometimes provide this capability out of the box). The choice of how to constrain which declaration is the target is rather arbitrary; one might define by the path from the root of the global namespace to get to get to it as OP hints in his example:
... declaration_in(i,"Room.prototype") ...
One will still need scope lookup rules to process such a path.
We remark that no matter which PTS is chosen by OP, scoping lookup will be required for accurate renaming. Many of the other PTS (TXL, Stratego, ...) provide no support whatever for implementing this.