@@ -22,6 +22,11 @@ limitations under the License.
2222// script, this wrapper strips out and propagates `--inspect`-like arguments
2323// via `NODE_DEBUG`. When executing an app script, this wrapper then inlines
2424// the `NODE_DEBUG` when found.
25+ //
26+ // A certain set of node_modules scripts are treated as if they are application scripts.
27+ // The WRAPPER_ALLOWED environment variable allows identifying node_modules scripts
28+ // that should be treated as application scripts, meaning that they load and execute
29+ // the user's scripts directly.
2530package main
2631
2732import (
@@ -37,6 +42,9 @@ import (
3742 "github.com/sirupsen/logrus"
3843)
3944
45+ // the next.js launcher loads user scripts directly
46+ var allowedNodeModules = []string {"node_modules/.bin/next" }
47+
4048// nodeContext allows manipulating the launch context for node.
4149type nodeContext struct {
4250 program string
@@ -47,7 +55,7 @@ type nodeContext struct {
4755func main () {
4856 env := envToMap (os .Environ ())
4957 logrus .SetLevel (logrusLevel (env ))
50-
58+
5159 logrus .Debugln ("Launched: " , os .Args )
5260
5361 // suppress npm warnings when node on PATH isn't the node used for npm
@@ -79,31 +87,36 @@ func run(nc *nodeContext, stdin io.Reader, stdout, stderr io.Writer) error {
7987 return fmt .Errorf ("could not unwrap: %w" , err )
8088 }
8189 logrus .Debugln ("unwrapped: " , nc .program )
82-
90+
8391 if ! isEnabled (nc .env ) {
8492 logrus .Info ("wrapper disabled" )
8593 return nc .exec (stdin , stdout , stderr )
8694 }
8795
88- // Use an absolute path in case we're being run within a node_modules directory
89- // If there's an error, then hand off immediately to the real node.
96+ // script may be "" such as when the script is piped in through stdin
9097 script := findScript (nc .args )
91- if abs , err := filepath .Abs (script ); err == nil {
92- script = abs
93- } else {
94- logrus .Warn ("could not access script: " , err )
95- return nc .exec (stdin , stdout , stderr )
96- }
98+ if script != "" {
99+ // Use an absolute path in case we're being run within a node_modules directory
100+ // If there's an error, then hand off immediately to the real node.
101+ if abs , err := filepath .Abs (script ); err == nil {
102+ script = abs
103+ } else {
104+ logrus .Warn ("could not access script: " , err )
105+ return nc .exec (stdin , stdout , stderr )
106+ }
107+ }
97108 logrus .Debugln ("script: " , script )
98109
110+ // If NODE_DEBUG is set then our parent process was this wrapper, and
111+ // NODE_DEBUG contains the --inspect* argument provided back then.
99112 nodeDebugOption , hasNodeDebug := nc .env ["NODE_DEBUG" ]
100113 if hasNodeDebug {
101114 logrus .Debugln ("found NODE_DEBUG=" , nodeDebugOption )
102115 }
103116
104- // if we're about to execute the application script, install the NODE_DEBUG
117+ // If we're about to execute the application script, install the NODE_DEBUG
105118 // arguments if found and go
106- if isApplicationScript (script ) || script == "" {
119+ if script == "" || isApplicationScript (script ) || isAllowedNodeModule ( script , nc . env ) {
107120 if hasNodeDebug {
108121 nc .stripInspectArgs () // top-level debug options win
109122 nc .addNodeArg (nodeDebugOption )
@@ -255,6 +268,23 @@ func isApplicationScript(path string) bool {
255268 ! strings .HasSuffix (path , "/bin/npm" )
256269}
257270
271+ // isAllowedNodeModule returns true if the script is an allowed node_module, meaning
272+ // one that is or directly launches the user's code.
273+ func isAllowedNodeModule (path string , env map [string ]string ) bool {
274+ allowedList := allowedNodeModules
275+ if v , found := env ["WRAPPER_ALLOWED" ]; found {
276+ split := strings .Split (v , " " )
277+ allowedList = append (allowedList , split ... )
278+ }
279+ for _ , allowed := range allowedList {
280+ if strings .HasSuffix (path , allowed ) {
281+ logrus .Infof ("script %q matches %q from allowed node_modules" , path , allowed )
282+ return true
283+ }
284+ }
285+ return false
286+ }
287+
258288// envToMap turns a set of VAR=VALUE strings to a map.
259289func envToMap (entries []string ) map [string ]string {
260290 m := make (map [string ]string )
0 commit comments