From ef88b391a785009059c71f20fd8c50e01b64cd14 Mon Sep 17 00:00:00 2001 From: Andrew Bradley Date: Tue, 28 Jul 2020 22:04:47 -0400 Subject: [PATCH] Fix #1072 --- dist-raw/node-esm-resolve-implementation.js | 32 +------- dist-raw/node-options.js | 83 +++++++++++++++++++++ 2 files changed, 84 insertions(+), 31 deletions(-) create mode 100644 dist-raw/node-options.js diff --git a/dist-raw/node-esm-resolve-implementation.js b/dist-raw/node-esm-resolve-implementation.js index 1a5846673..a3da2f9a0 100644 --- a/dist-raw/node-esm-resolve-implementation.js +++ b/dist-raw/node-esm-resolve-implementation.js @@ -50,37 +50,7 @@ const { Stats, } = require('fs'); // const { getOptionValue } = require('internal/options'); -const { getOptionValue } = (() => { - let options; - function parseOptions() { - if (!options) { - options = { - '--preserve-symlinks': false, - '--preserve-symlinks-main': false, - '--input-type': undefined, - '--experimental-specifier-resolution': 'explicit', - ...parseExecArgv() - } - } - }; - function parseExecArgv () { - return require('arg')({ - '--preserve-symlinks': Boolean, - '--preserve-symlinks-main': Boolean, - '--input-type': String, - '--experimental-specifier-resolution': String - }, { - argv: process.execArgv, - permissive: true - }); - } - return { - getOptionValue: (opt) => { - parseOptions(); - return options[opt]; - } - }; -})(); +const { getOptionValue } = require('./node-options'); const { sep } = require('path'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); diff --git a/dist-raw/node-options.js b/dist-raw/node-options.js new file mode 100644 index 000000000..f27a44689 --- /dev/null +++ b/dist-raw/node-options.js @@ -0,0 +1,83 @@ +// Replacement for node's internal 'internal/options' module + +exports.getOptionValue = getOptionValue; +function getOptionValue(opt) { + parseOptions(); + return options[opt]; +} + +let options; +function parseOptions() { + if (!options) { + options = { + '--preserve-symlinks': false, + '--preserve-symlinks-main': false, + '--input-type': undefined, + '--experimental-specifier-resolution': 'explicit', + ...parseArgv(getNodeOptionsEnvArgv()), + ...parseArgv(process.execArgv) + } + } +} + +function parseArgv(argv) { + return require('arg')({ + '--preserve-symlinks': Boolean, + '--preserve-symlinks-main': Boolean, + '--input-type': String, + '--experimental-specifier-resolution': String + }, { + argv, + permissive: true + }); +} + +function getNodeOptionsEnvArgv() { + const errors = []; + const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || '', errors); + if (errors.length !== 0) { + // TODO: handle errors somehow + } + return envArgv; +} + +// Direct JS port of C implementation: https://github.com/nodejs/node/blob/67ba825037b4082d5d16f922fb9ce54516b4a869/src/node_options.cc#L1024-L1063 +function ParseNodeOptionsEnvVar(node_options, errors) { + const env_argv = []; + + let is_in_string = false; + let will_start_new_arg = true; + for (let index = 0; index < node_options.length; ++index) { + let c = node_options[index]; + + // Backslashes escape the following character + if (c === '\\' && is_in_string) { + if (index + 1 === node_options.length) { + errors.push("invalid value for NODE_OPTIONS " + + "(invalid escape)\n"); + return env_argv; + } else { + c = node_options[++index]; + } + } else if (c === ' ' && !is_in_string) { + will_start_new_arg = true; + continue; + } else if (c === '"') { + is_in_string = !is_in_string; + continue; + } + + if (will_start_new_arg) { + env_argv.push(c); + will_start_new_arg = false; + } else { + env_argv[env_argv.length - 1] += c; + } + } + + if (is_in_string) { + errors.push("invalid value for NODE_OPTIONS " + + "(unterminated string)\n"); + } + return env_argv; +}