node-options.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Replacement for node's internal 'internal/options' module
  2. exports.getOptionValue = getOptionValue;
  3. function getOptionValue(opt) {
  4. parseOptions();
  5. return options[opt];
  6. }
  7. let options;
  8. function parseOptions() {
  9. if (!options) {
  10. options = {
  11. '--preserve-symlinks': false,
  12. '--preserve-symlinks-main': false,
  13. '--input-type': undefined,
  14. '--experimental-specifier-resolution': 'explicit',
  15. '--experimental-policy': undefined,
  16. '--conditions': [],
  17. '--pending-deprecation': false,
  18. ...parseArgv(getNodeOptionsEnvArgv()),
  19. ...parseArgv(process.execArgv),
  20. ...getOptionValuesFromOtherEnvVars()
  21. }
  22. }
  23. }
  24. function parseArgv(argv) {
  25. return require('arg')({
  26. '--preserve-symlinks': Boolean,
  27. '--preserve-symlinks-main': Boolean,
  28. '--input-type': String,
  29. '--experimental-specifier-resolution': String,
  30. // Legacy alias for node versions prior to 12.16
  31. '--es-module-specifier-resolution': '--experimental-specifier-resolution',
  32. '--experimental-policy': String,
  33. '--conditions': [String],
  34. '--pending-deprecation': Boolean,
  35. '--experimental-json-modules': Boolean,
  36. '--experimental-wasm-modules': Boolean,
  37. }, {
  38. argv,
  39. permissive: true
  40. });
  41. }
  42. function getNodeOptionsEnvArgv() {
  43. const errors = [];
  44. const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || '', errors);
  45. if (errors.length !== 0) {
  46. // TODO: handle errors somehow
  47. }
  48. return envArgv;
  49. }
  50. // Direct JS port of C implementation: https://github.com/nodejs/node/blob/67ba825037b4082d5d16f922fb9ce54516b4a869/src/node_options.cc#L1024-L1063
  51. function ParseNodeOptionsEnvVar(node_options, errors) {
  52. const env_argv = [];
  53. let is_in_string = false;
  54. let will_start_new_arg = true;
  55. for (let index = 0; index < node_options.length; ++index) {
  56. let c = node_options[index];
  57. // Backslashes escape the following character
  58. if (c === '\\' && is_in_string) {
  59. if (index + 1 === node_options.length) {
  60. errors.push("invalid value for NODE_OPTIONS " +
  61. "(invalid escape)\n");
  62. return env_argv;
  63. } else {
  64. c = node_options[++index];
  65. }
  66. } else if (c === ' ' && !is_in_string) {
  67. will_start_new_arg = true;
  68. continue;
  69. } else if (c === '"') {
  70. is_in_string = !is_in_string;
  71. continue;
  72. }
  73. if (will_start_new_arg) {
  74. env_argv.push(c);
  75. will_start_new_arg = false;
  76. } else {
  77. env_argv[env_argv.length - 1] += c;
  78. }
  79. }
  80. if (is_in_string) {
  81. errors.push("invalid value for NODE_OPTIONS " +
  82. "(unterminated string)\n");
  83. }
  84. return env_argv;
  85. }
  86. // Get option values that can be specified via env vars besides NODE_OPTIONS
  87. function getOptionValuesFromOtherEnvVars() {
  88. const options = {};
  89. if(process.env.NODE_PENDING_DEPRECATION === '1') {
  90. options['--pending-deprecation'] = true;
  91. }
  92. return options;
  93. }