diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 22f52952af54d4..70cdc214cdd5c2 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -9,13 +9,16 @@ "additionalProperties": false, "properties": { "addons": { - "type": "boolean" + "type": "boolean", + "description": "disable loading native addons" }, "allow-addons": { - "type": "boolean" + "type": "boolean", + "description": "allow use of addons when any permissions are set" }, "allow-child-process": { - "type": "boolean" + "type": "boolean", + "description": "allow use of child process when any permissions are set" }, "allow-fs-read": { "oneOf": [ @@ -29,7 +32,8 @@ }, "type": "array" } - ] + ], + "description": "allow permissions to read the filesystem" }, "allow-fs-write": { "oneOf": [ @@ -43,22 +47,28 @@ }, "type": "array" } - ] + ], + "description": "allow permissions to write in the filesystem" }, "allow-inspector": { - "type": "boolean" + "type": "boolean", + "description": "allow use of inspector when any permissions are set" }, "allow-net": { - "type": "boolean" + "type": "boolean", + "description": "allow use of network when any permissions are set" }, "allow-wasi": { - "type": "boolean" + "type": "boolean", + "description": "allow wasi when any permissions are set" }, "allow-worker": { - "type": "boolean" + "type": "boolean", + "description": "allow worker threads when any permissions are set" }, "async-context-frame": { - "type": "boolean" + "type": "boolean", + "description": "Improve AsyncLocalStorage performance with AsyncContextFrame" }, "conditions": { "oneOf": [ @@ -72,34 +82,44 @@ }, "type": "array" } - ] + ], + "description": "additional user conditions for conditional exports and imports" }, "cpu-prof": { - "type": "boolean" + "type": "boolean", + "description": "Start the V8 CPU profiler on start up, and write the CPU profile to disk before exit. If --cpu-prof-dir is not specified, write the profile to the current working directory." }, "cpu-prof-dir": { - "type": "string" + "type": "string", + "description": "Directory where the V8 profiles generated by --cpu-prof will be placed. Does not affect --prof." }, "cpu-prof-interval": { - "type": "number" + "type": "number", + "description": "specified sampling interval in microseconds for the V8 CPU profile generated with --cpu-prof. (default: 1000)" }, "cpu-prof-name": { - "type": "string" + "type": "string", + "description": "specified file name of the V8 CPU profile generated with --cpu-prof" }, "debug-arraybuffer-allocations": { - "type": "boolean" + "type": "boolean", + "description": "" }, "deprecation": { - "type": "boolean" + "type": "boolean", + "description": "silence deprecation warnings" }, "diagnostic-dir": { - "type": "string" + "type": "string", + "description": "set dir for all output files (default: current working directory)" }, "disable-proto": { - "type": "string" + "type": "string", + "description": "disable Object.prototype.__proto__" }, "disable-sigusr1": { - "type": "boolean" + "type": "boolean", + "description": "Disable inspector thread to be listening for SIGUSR1 signal" }, "disable-warning": { "oneOf": [ @@ -113,37 +133,48 @@ }, "type": "array" } - ] + ], + "description": "silence specific process warnings" }, "disable-wasm-trap-handler": { - "type": "boolean" + "type": "boolean", + "description": "Disable trap-handler-based WebAssembly bound checks. V8 will insert inline bound checks when compiling WebAssembly which may slow down performance." }, "dns-result-order": { - "type": "string" + "type": "string", + "description": "set default value of verbatim in dns.lookup. Options are 'ipv4first' (IPv4 addresses are placed before IPv6 addresses) 'ipv6first' (IPv6 addresses are placed before IPv4 addresses) 'verbatim' (addresses are in the order the DNS resolver returned)" }, "enable-fips": { - "type": "boolean" + "type": "boolean", + "description": "enable FIPS crypto at startup" }, "enable-source-maps": { - "type": "boolean" + "type": "boolean", + "description": "Source Map V3 support for stack traces" }, "entry-url": { - "type": "boolean" + "type": "boolean", + "description": "Treat the entrypoint as a URL" }, "experimental-addon-modules": { - "type": "boolean" + "type": "boolean", + "description": "experimental import support for addons" }, "experimental-detect-module": { - "type": "boolean" + "type": "boolean", + "description": "when ambiguous modules fail to evaluate because they contain ES module syntax, try again to evaluate them as ES modules" }, "experimental-eventsource": { - "type": "boolean" + "type": "boolean", + "description": "experimental EventSource API" }, "experimental-global-navigator": { - "type": "boolean" + "type": "boolean", + "description": "expose experimental Navigator API on the global scope" }, "experimental-import-meta-resolve": { - "type": "boolean" + "type": "boolean", + "description": "experimental ES Module import.meta.resolve() parentURL support" }, "experimental-loader": { "oneOf": [ @@ -157,79 +188,104 @@ }, "type": "array" } - ] + ], + "description": "use the specified module as a custom loader" }, "experimental-print-required-tla": { - "type": "boolean" + "type": "boolean", + "description": "Print pending top-level await. If --experimental-require-module is true, evaluate asynchronous graphs loaded by `require()` but do not run the microtasks, in order to to find and print top-level await in the graph" }, "experimental-quic": { - "type": "boolean" + "type": "boolean", + "description": "experimental QUIC support" }, "experimental-repl-await": { - "type": "boolean" + "type": "boolean", + "description": "experimental await keyword support in REPL" }, "experimental-require-module": { - "type": "boolean" + "type": "boolean", + "description": "Allow loading synchronous ES Modules in require()." }, "experimental-shadow-realm": { - "type": "boolean" + "type": "boolean", + "description": "" }, "experimental-sqlite": { - "type": "boolean" + "type": "boolean", + "description": "experimental node:sqlite module" }, "experimental-transform-types": { - "type": "boolean" + "type": "boolean", + "description": "enable transformation of TypeScript-onlysyntax into JavaScript code" }, "experimental-vm-modules": { - "type": "boolean" + "type": "boolean", + "description": "experimental ES Module support in vm module" }, "experimental-websocket": { - "type": "boolean" + "type": "boolean", + "description": "experimental WebSocket API" }, "experimental-webstorage": { - "type": "boolean" + "type": "boolean", + "description": "experimental Web Storage API" }, "extra-info-on-fatal-exception": { - "type": "boolean" + "type": "boolean", + "description": "hide extra information on fatal exception that causes exit" }, "force-async-hooks-checks": { - "type": "boolean" + "type": "boolean", + "description": "disable checks for async_hooks" }, "force-context-aware": { - "type": "boolean" + "type": "boolean", + "description": "disable loading non-context-aware addons" }, "force-fips": { - "type": "boolean" + "type": "boolean", + "description": "force FIPS crypto (cannot be disabled)" }, "force-node-api-uncaught-exceptions-policy": { - "type": "boolean" + "type": "boolean", + "description": "enforces 'uncaughtException' event on Node API asynchronous callbacks" }, "frozen-intrinsics": { - "type": "boolean" + "type": "boolean", + "description": "experimental frozen intrinsics support" }, "global-search-paths": { - "type": "boolean" + "type": "boolean", + "description": "disable global module search paths" }, "heap-prof": { - "type": "boolean" + "type": "boolean", + "description": "Start the V8 heap profiler on start up, and write the heap profile to disk before exit. If --heap-prof-dir is not specified, write the profile to the current working directory." }, "heap-prof-dir": { - "type": "string" + "type": "string", + "description": "Directory where the V8 heap profiles generated by --heap-prof will be placed." }, "heap-prof-interval": { - "type": "number" + "type": "number", + "description": "specified sampling interval in bytes for the V8 heap profile generated with --heap-prof. (default: 512 * 1024)" }, "heap-prof-name": { - "type": "string" + "type": "string", + "description": "specified file name of the V8 heap profile generated with --heap-prof" }, "heapsnapshot-near-heap-limit": { - "type": "number" + "type": "number", + "description": "Generate heap snapshots whenever V8 is approaching the heap limit. No more than the specified number of heap snapshots will be generated." }, "heapsnapshot-signal": { - "type": "string" + "type": "string", + "description": "Generate heap snapshot on specified signal" }, "icu-data-dir": { - "type": "string" + "type": "string", + "description": "set ICU data load path to dir (overrides NODE_ICU_DATA) (note: linked-in ICU data is present)" }, "import": { "oneOf": [ @@ -243,97 +299,128 @@ }, "type": "array" } - ] + ], + "description": "ES module to preload (option can be repeated)" }, "input-type": { - "type": "string" + "type": "string", + "description": "set module type for string input" }, "insecure-http-parser": { - "type": "boolean" + "type": "boolean", + "description": "use an insecure HTTP parser that accepts invalid HTTP headers" }, "inspect": { - "type": "boolean" + "type": "boolean", + "description": "activate inspector on host:port (default: 127.0.0.1:9229)" }, "inspect-brk": { - "type": "boolean" + "type": "boolean", + "description": "activate inspector on host:port and break at start of user script" }, "inspect-port": { - "type": "number" + "type": "number", + "description": "set host:port for inspector" }, "inspect-publish-uid": { - "type": "string" + "type": "string", + "description": "comma separated list of destinations for inspector uid(default: stderr,http)" }, "inspect-wait": { - "type": "boolean" + "type": "boolean", + "description": "activate inspector on host:port and wait for debugger to be attached" }, "localstorage-file": { - "type": "string" + "type": "string", + "description": "file used to persist localStorage data" }, "max-http-header-size": { - "type": "number" + "type": "number", + "description": "set the maximum size of HTTP headers (default: 16384 (16KB))" }, "max-old-space-size-percentage": { - "type": "string" + "type": "string", + "description": "set V8's max old space size as a percentage of available memory (e.g., '50%'). Takes precedence over --max-old-space-size." }, "network-family-autoselection": { - "type": "boolean" + "type": "boolean", + "description": "Disable network address family autodetection algorithm" }, "network-family-autoselection-attempt-timeout": { - "type": "number" + "type": "number", + "description": "Sets the default value for the network family autoselection attempt timeout." }, "node-snapshot": { - "type": "boolean" + "type": "boolean", + "description": "" }, "openssl-config": { - "type": "string" + "type": "string", + "description": "load OpenSSL configuration from the specified file (overrides OPENSSL_CONF)" }, "openssl-legacy-provider": { - "type": "boolean" + "type": "boolean", + "description": "enable OpenSSL 3.0 legacy provider" }, "openssl-shared-config": { - "type": "boolean" + "type": "boolean", + "description": "enable OpenSSL shared configuration" }, "pending-deprecation": { - "type": "boolean" + "type": "boolean", + "description": "emit pending deprecation warnings" }, "permission": { - "type": "boolean" + "type": "boolean", + "description": "enable the permission system" }, "preserve-symlinks": { - "type": "boolean" + "type": "boolean", + "description": "preserve symbolic links when resolving" }, "preserve-symlinks-main": { - "type": "boolean" + "type": "boolean", + "description": "preserve symbolic links when resolving the main module" }, "redirect-warnings": { - "type": "string" + "type": "string", + "description": "write warnings to file instead of stderr" }, "report-compact": { - "type": "boolean" + "type": "boolean", + "description": "output compact single-line JSON" }, "report-dir": { - "type": "string" + "type": "string", + "description": "define custom report pathname. (default: current working directory)" }, "report-exclude-env": { - "type": "boolean" + "type": "boolean", + "description": "Exclude environment variables when generating report (default: false)" }, "report-exclude-network": { - "type": "boolean" + "type": "boolean", + "description": "exclude network interface diagnostics. (default: false)" }, "report-filename": { - "type": "string" + "type": "string", + "description": "define custom report file name. (default: YYYYMMDD.HHMMSS.PID.SEQUENCE#.txt)" }, "report-on-fatalerror": { - "type": "boolean" + "type": "boolean", + "description": "generate diagnostic report on fatal (internal) errors" }, "report-on-signal": { - "type": "boolean" + "type": "boolean", + "description": "generate diagnostic report upon receiving signals" }, "report-signal": { - "type": "string" + "type": "string", + "description": "causes diagnostic report to be produced on provided signal, unsupported in Windows. (default: SIGUSR2)" }, "report-uncaught-exception": { - "type": "boolean" + "type": "boolean", + "description": "generate diagnostic report on uncaught exceptions" }, "require": { "oneOf": [ @@ -347,25 +434,32 @@ }, "type": "array" } - ] + ], + "description": "CommonJS module to preload (option can be repeated)" }, "secure-heap": { - "type": "number" + "type": "number", + "description": "total size of the OpenSSL secure heap" }, "secure-heap-min": { - "type": "number" + "type": "number", + "description": "minimum allocation size from the OpenSSL secure heap" }, "snapshot-blob": { - "type": "string" + "type": "string", + "description": "Path to the snapshot blob that's either the result of snapshotbuilding, or the blob that is used to restore the application state" }, "stack-trace-limit": { - "type": "number" + "type": "number", + "description": "" }, "strip-types": { - "type": "boolean" + "type": "boolean", + "description": "Type-stripping for TypeScript files." }, "test-coverage-branches": { - "type": "number" + "type": "number", + "description": "the branch coverage minimum threshold" }, "test-coverage-exclude": { "oneOf": [ @@ -379,10 +473,12 @@ }, "type": "array" } - ] + ], + "description": "exclude files from coverage report that match this glob pattern" }, "test-coverage-functions": { - "type": "number" + "type": "number", + "description": "the function coverage minimum threshold" }, "test-coverage-include": { "oneOf": [ @@ -396,16 +492,20 @@ }, "type": "array" } - ] + ], + "description": "include files in coverage report that match this glob pattern" }, "test-coverage-lines": { - "type": "number" + "type": "number", + "description": "the line coverage minimum threshold" }, "test-global-setup": { - "type": "string" + "type": "string", + "description": "specifies the path to the global setup file" }, "test-isolation": { - "type": "string" + "type": "string", + "description": "configures the type of test isolation used in the test runner" }, "test-name-pattern": { "oneOf": [ @@ -419,10 +519,12 @@ }, "type": "array" } - ] + ], + "description": "run tests whose name matches this regular expression" }, "test-only": { - "type": "boolean" + "type": "boolean", + "description": "run tests with 'only' option set" }, "test-reporter": { "oneOf": [ @@ -436,7 +538,8 @@ }, "type": "array" } - ] + ], + "description": "report test output using the given reporter" }, "test-reporter-destination": { "oneOf": [ @@ -450,13 +553,16 @@ }, "type": "array" } - ] + ], + "description": "report given reporter to the given destination" }, "test-rerun-failures": { - "type": "string" + "type": "string", + "description": "specifies the path to the rerun state file" }, "test-shard": { - "type": "string" + "type": "string", + "description": "run test at specific shard" }, "test-skip-pattern": { "oneOf": [ @@ -470,115 +576,152 @@ }, "type": "array" } - ] + ], + "description": "run tests whose name do not match this regular expression" }, "throw-deprecation": { - "type": "boolean" + "type": "boolean", + "description": "throw an exception on deprecations" }, "title": { - "type": "string" + "type": "string", + "description": "the process title to use on startup" }, "tls-cipher-list": { - "type": "string" + "type": "string", + "description": "use an alternative default TLS cipher list" }, "tls-keylog": { - "type": "string" + "type": "string", + "description": "log TLS decryption keys to named file for traffic analysis" }, "tls-max-v1.2": { - "type": "boolean" + "type": "boolean", + "description": "set default TLS maximum to TLSv1.2 (default: TLSv1.3)" }, "tls-max-v1.3": { - "type": "boolean" + "type": "boolean", + "description": "set default TLS maximum to TLSv1.3 (default: TLSv1.3)" }, "tls-min-v1.0": { - "type": "boolean" + "type": "boolean", + "description": "set default TLS minimum to TLSv1.0 (default: TLSv1.2)" }, "tls-min-v1.1": { - "type": "boolean" + "type": "boolean", + "description": "set default TLS minimum to TLSv1.1 (default: TLSv1.2)" }, "tls-min-v1.2": { - "type": "boolean" + "type": "boolean", + "description": "set default TLS minimum to TLSv1.2 (default: TLSv1.2)" }, "tls-min-v1.3": { - "type": "boolean" + "type": "boolean", + "description": "set default TLS minimum to TLSv1.3 (default: TLSv1.2)" }, "trace-deprecation": { - "type": "boolean" + "type": "boolean", + "description": "show stack traces on deprecations" }, "trace-env": { - "type": "boolean" + "type": "boolean", + "description": "Print accesses to the environment variables" }, "trace-env-js-stack": { - "type": "boolean" + "type": "boolean", + "description": "Print accesses to the environment variables and the JavaScript stack trace" }, "trace-env-native-stack": { - "type": "boolean" + "type": "boolean", + "description": "Print accesses to the environment variables and the native stack trace" }, "trace-event-categories": { - "type": "string" + "type": "string", + "description": "comma separated list of trace event categories to record" }, "trace-event-file-pattern": { - "type": "string" + "type": "string", + "description": "Template string specifying the filepath for the trace-events data, it supports ${rotation} and ${pid}." }, "trace-exit": { - "type": "boolean" + "type": "boolean", + "description": "show stack trace when an environment exits" }, "trace-promises": { - "type": "boolean" + "type": "boolean", + "description": "show stack traces on promise initialization and resolution" }, "trace-require-module": { - "type": "string" + "type": "string", + "description": "Print access to require(esm). Options are 'all' (print all usage) and 'no-node-modules' (excluding usage from the node_modules folder)" }, "trace-sigint": { - "type": "boolean" + "type": "boolean", + "description": "enable printing JavaScript stacktrace on SIGINT" }, "trace-sync-io": { - "type": "boolean" + "type": "boolean", + "description": "show stack trace when use of sync IO is detected after the first tick" }, "trace-tls": { - "type": "boolean" + "type": "boolean", + "description": "prints TLS packet trace information to stderr" }, "trace-uncaught": { - "type": "boolean" + "type": "boolean", + "description": "show stack traces for the `throw` behind uncaught exceptions" }, "trace-warnings": { - "type": "boolean" + "type": "boolean", + "description": "show stack traces on process warnings" }, "track-heap-objects": { - "type": "boolean" + "type": "boolean", + "description": "track heap object allocations for heap snapshots" }, "unhandled-rejections": { - "type": "string" + "type": "string", + "description": "define unhandled rejections behavior. Options are 'strict' (always raise an error), 'throw' (raise an error unless 'unhandledRejection' hook is set), 'warn' (log a warning), 'none' (silence warnings), 'warn-with-error-code' (log a warning and set exit code 1 unless 'unhandledRejection' hook is set). (default: throw)" }, "use-bundled-ca": { - "type": "boolean" + "type": "boolean", + "description": "use bundled CA store (default)" }, "use-env-proxy": { - "type": "boolean" + "type": "boolean", + "description": "parse proxy settings from HTTP_PROXY/HTTPS_PROXY/NO_PROXYenvironment variables and apply the setting in global HTTP/HTTPS clients" }, "use-largepages": { - "type": "string" + "type": "string", + "description": "Map the Node.js static code to large pages. Options are 'off' (the default value, meaning do not map), 'on' (map and ignore failure, reporting it to stderr), or 'silent' (map and silently ignore failure)" }, "use-openssl-ca": { - "type": "boolean" + "type": "boolean", + "description": "use OpenSSL's default CA store" }, "use-system-ca": { - "type": "boolean" + "type": "boolean", + "description": "use system's CA store" }, "v8-pool-size": { - "type": "number" + "type": "number", + "description": "set V8's thread pool size" }, "verify-base-objects": { - "type": "boolean" + "type": "boolean", + "description": "" }, "warnings": { - "type": "boolean" + "type": "boolean", + "description": "silence all process warnings" }, "watch": { - "type": "boolean" + "type": "boolean", + "description": "run in watch mode" }, "watch-kill-signal": { - "type": "string" + "type": "string", + "description": "kill signal to send to the process on watch mode restarts(default: SIGTERM)" }, "watch-path": { "oneOf": [ @@ -592,13 +735,16 @@ }, "type": "array" } - ] + ], + "description": "path to watch" }, "watch-preserve-output": { - "type": "boolean" + "type": "boolean", + "description": "preserve outputs on watch mode restart" }, "zero-fill-buffers": { - "type": "boolean" + "type": "boolean", + "description": "automatically zero-fill all newly allocated Buffer instances" } }, "type": "object" @@ -608,10 +754,12 @@ "additionalProperties": false, "properties": { "allow-addons": { - "type": "boolean" + "type": "boolean", + "description": "allow use of addons when any permissions are set" }, "allow-child-process": { - "type": "boolean" + "type": "boolean", + "description": "allow use of child process when any permissions are set" }, "allow-fs-read": { "oneOf": [ @@ -625,7 +773,8 @@ }, "type": "array" } - ] + ], + "description": "allow permissions to read the filesystem" }, "allow-fs-write": { "oneOf": [ @@ -639,22 +788,28 @@ }, "type": "array" } - ] + ], + "description": "allow permissions to write in the filesystem" }, "allow-inspector": { - "type": "boolean" + "type": "boolean", + "description": "allow use of inspector when any permissions are set" }, "allow-net": { - "type": "boolean" + "type": "boolean", + "description": "allow use of network when any permissions are set" }, "allow-wasi": { - "type": "boolean" + "type": "boolean", + "description": "allow wasi when any permissions are set" }, "allow-worker": { - "type": "boolean" + "type": "boolean", + "description": "allow worker threads when any permissions are set" }, "permission": { - "type": "boolean" + "type": "boolean", + "description": "enable the permission system" } } }, @@ -663,19 +818,24 @@ "additionalProperties": false, "properties": { "experimental-test-coverage": { - "type": "boolean" + "type": "boolean", + "description": "enable code coverage in the test runner" }, "experimental-test-module-mocks": { - "type": "boolean" + "type": "boolean", + "description": "enable module mocking in the test runner" }, "test": { - "type": "boolean" + "type": "boolean", + "description": "launch test runner on startup" }, "test-concurrency": { - "type": "number" + "type": "number", + "description": "specify test runner concurrency" }, "test-coverage-branches": { - "type": "number" + "type": "number", + "description": "the branch coverage minimum threshold" }, "test-coverage-exclude": { "oneOf": [ @@ -689,10 +849,12 @@ }, "type": "array" } - ] + ], + "description": "exclude files from coverage report that match this glob pattern" }, "test-coverage-functions": { - "type": "number" + "type": "number", + "description": "the function coverage minimum threshold" }, "test-coverage-include": { "oneOf": [ @@ -706,19 +868,24 @@ }, "type": "array" } - ] + ], + "description": "include files in coverage report that match this glob pattern" }, "test-coverage-lines": { - "type": "number" + "type": "number", + "description": "the line coverage minimum threshold" }, "test-force-exit": { - "type": "boolean" + "type": "boolean", + "description": "force test runner to exit upon completion" }, "test-global-setup": { - "type": "string" + "type": "string", + "description": "specifies the path to the global setup file" }, "test-isolation": { - "type": "string" + "type": "string", + "description": "configures the type of test isolation used in the test runner" }, "test-name-pattern": { "oneOf": [ @@ -732,10 +899,12 @@ }, "type": "array" } - ] + ], + "description": "run tests whose name matches this regular expression" }, "test-only": { - "type": "boolean" + "type": "boolean", + "description": "run tests with 'only' option set" }, "test-reporter": { "oneOf": [ @@ -749,7 +918,8 @@ }, "type": "array" } - ] + ], + "description": "report test output using the given reporter" }, "test-reporter-destination": { "oneOf": [ @@ -763,13 +933,16 @@ }, "type": "array" } - ] + ], + "description": "report given reporter to the given destination" }, "test-rerun-failures": { - "type": "string" + "type": "string", + "description": "specifies the path to the rerun state file" }, "test-shard": { - "type": "string" + "type": "string", + "description": "run test at specific shard" }, "test-skip-pattern": { "oneOf": [ @@ -783,13 +956,16 @@ }, "type": "array" } - ] + ], + "description": "run tests whose name do not match this regular expression" }, "test-timeout": { - "type": "number" + "type": "number", + "description": "specify test runner timeout" }, "test-update-snapshots": { - "type": "boolean" + "type": "boolean", + "description": "regenerate test snapshots" } } }, @@ -798,10 +974,12 @@ "additionalProperties": false, "properties": { "watch": { - "type": "boolean" + "type": "boolean", + "description": "run in watch mode" }, "watch-kill-signal": { - "type": "string" + "type": "string", + "description": "kill signal to send to the process on watch mode restarts(default: SIGTERM)" }, "watch-path": { "oneOf": [ @@ -815,10 +993,12 @@ }, "type": "array" } - ] + ], + "description": "path to watch" }, "watch-preserve-output": { - "type": "boolean" + "type": "boolean", + "description": "preserve outputs on watch mode restart" } } } diff --git a/lib/internal/options.js b/lib/internal/options.js index be1dc6a842c526..cb77f0841053f6 100644 --- a/lib/internal/options.js +++ b/lib/internal/options.js @@ -3,6 +3,7 @@ const { ArrayPrototypeMap, ArrayPrototypeSort, + ObjectEntries, ObjectFromEntries, ObjectKeys, StringPrototypeReplace, @@ -48,7 +49,8 @@ function generateConfigJsonSchema() { const envOptionsMap = getEnvOptionsInputType(); const namespaceOptionsMap = getNamespaceOptionsInputType(); - function createPropertyForType(type) { + function createPropertyForOptionDetail(detail) { + const { type, description } = detail; if (type === 'array') { return { __proto__: null, @@ -56,10 +58,11 @@ function generateConfigJsonSchema() { { __proto__: null, type: 'string' }, { __proto__: null, items: { __proto__: null, type: 'string', minItems: 1 }, type: 'array' }, ], + description, }; } - return { __proto__: null, type }; + return { __proto__: null, type, description }; } const schema = { @@ -87,9 +90,9 @@ function generateConfigJsonSchema() { const nodeOptions = rootProperties.nodeOptions.properties; // Add env options to nodeOptions (backward compatibility) - for (const { 0: key, 1: type } of envOptionsMap) { + for (const { 0: key, 1: type } of ObjectEntries(envOptionsMap)) { const keyWithoutPrefix = StringPrototypeReplace(key, '--', ''); - nodeOptions[keyWithoutPrefix] = createPropertyForType(type); + nodeOptions[keyWithoutPrefix] = createPropertyForOptionDetail(type); } // Add namespace properties at the root level @@ -105,9 +108,9 @@ function generateConfigJsonSchema() { const namespaceProperties = rootProperties[namespace].properties; // Add all options for this namespace - for (const { 0: optionName, 1: optionType } of optionsMap) { + for (const { 0: optionName, 1: optionType } of ObjectEntries(optionsMap)) { const keyWithoutPrefix = StringPrototypeReplace(optionName, '--', ''); - namespaceProperties[keyWithoutPrefix] = createPropertyForType(optionType); + namespaceProperties[keyWithoutPrefix] = createPropertyForOptionDetail(optionType); } // Sort the namespace properties alphabetically diff --git a/src/node_config_file.cc b/src/node_config_file.cc index 39ea8f3a0634fd..4205a3cee7e52a 100644 --- a/src/node_config_file.cc +++ b/src/node_config_file.cc @@ -38,11 +38,12 @@ std::optional ConfigReader::GetDataFromArgs( } ParseResult ConfigReader::ProcessOptionValue( - const std::pair& option_info, + const std::pair& + option_details, simdjson::ondemand::value* option_value, std::vector* output) { - const std::string& option_name = option_info.first; - const options_parser::OptionType option_type = option_info.second; + const std::string& option_name = option_details.first; + const options_parser::OptionType option_type = option_details.second.type; switch (option_type) { case options_parser::OptionType::kBoolean: { @@ -153,7 +154,8 @@ ParseResult ConfigReader::ParseOptions( std::unordered_set* unique_options, const std::string& namespace_name) { // Determine which options map to use and output vector - std::unordered_map options_map; + std::unordered_map + options_map; std::vector* output_vector; if (namespace_name == "nodeOptions") { diff --git a/src/node_config_file.h b/src/node_config_file.h index b369dca97b0062..82874cee8b583f 100644 --- a/src/node_config_file.h +++ b/src/node_config_file.h @@ -46,7 +46,8 @@ class ConfigReader { // Process a single option value based on its type ParseResult ProcessOptionValue( - const std::pair& option_info, + const std::pair& + option_details, simdjson::ondemand::value* option_value, std::vector* output); @@ -54,7 +55,8 @@ class ConfigReader { std::vector namespace_options_; // Cache for fast lookup of environment options - std::unordered_map env_options_map_; + std::unordered_map + env_options_map_; bool env_options_initialized_ = false; }; diff --git a/src/node_options.cc b/src/node_options.cc index 07a466e299dac4..eb2c021bac0c60 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -304,13 +304,13 @@ namespace options_parser { // Helper function to convert option types to their string representation // and add them to a V8 Map -static bool AddOptionTypeToMap(Isolate* isolate, - Local context, - Local map, - const std::string& option_name, - const OptionType& option_type) { +static bool AddOptionTypeToObject(Isolate* isolate, + Local context, + Local object, + const std::string& option_name, + const OptionMappingDetails& option_details) { std::string type; - switch (static_cast(option_type)) { + switch (static_cast(option_details.type)) { case 0: // No-op case 1: // V8 flags break; // V8 and NoOp flags are not supported @@ -353,7 +353,26 @@ static bool AddOptionTypeToMap(Isolate* isolate, return true; // Skip this entry but continue processing } - if (map->Set(context, option_key, type_value).IsEmpty()) { + Local help_text; + if (!String::NewFromUtf8(isolate, + option_details.help_text.data(), + v8::NewStringType::kNormal, + option_details.help_text.size()) + .ToLocal(&help_text)) { + return true; // Skip this entry but continue processing + } + + // Create an object with type and help_text properties + Local null_value = Null(isolate); + constexpr size_t kOptionInfoLength = 2; + std::array, kOptionInfoLength> names = { + String::NewFromUtf8Literal(isolate, "type"), + String::NewFromUtf8Literal(isolate, "description")}; + std::array, kOptionInfoLength> values = {type_value, help_text}; + Local option_info = Object::New( + isolate, null_value, names.data(), values.data(), kOptionInfoLength); + + if (object->Set(context, option_key, option_info).IsNothing()) { return false; // Error occurred, stop processing } @@ -1521,14 +1540,19 @@ std::string GetBashCompletion() { return out.str(); } -std::unordered_map +std::unordered_map MapEnvOptionsFlagInputType() { - std::unordered_map type_map; + std::unordered_map + type_map; const auto& parser = _ppop_instance; for (const auto& item : parser.options_) { if (!item.first.empty() && !item.first.starts_with('[') && item.second.env_setting == kAllowedInEnvvar) { - type_map[item.first] = item.second.type; + const auto mapping_details = options_parser::OptionMappingDetails{ + item.second.type, + item.second.help_text, + }; + type_map[item.first] = mapping_details; } } return type_map; @@ -1548,27 +1572,33 @@ std::vector MapAvailableNamespaces() { return namespaceNames; } -std::unordered_map +std::unordered_map MapOptionsByNamespace(std::string namespace_name) { - std::unordered_map type_map; + std::unordered_map + type_map; const auto& parser = _ppop_instance; for (const auto& item : parser.options_) { if (!item.first.empty() && !item.first.starts_with('[') && item.second.namespace_id == namespace_name) { - type_map[item.first] = item.second.type; + const auto mapping_details = options_parser::OptionMappingDetails{ + item.second.type, + item.second.help_text, + }; + type_map[item.first] = mapping_details; } } return type_map; } -std::unordered_map> +std::unordered_map< + std::string, + std::unordered_map> MapNamespaceOptionsAssociations() { std::vector available_namespaces = options_parser::MapAvailableNamespaces(); std::unordered_map< std::string, - std::unordered_map> + std::unordered_map> namespace_option_mapping; for (const std::string& available_namespace : available_namespaces) { namespace_option_mapping[available_namespace] = @@ -1821,9 +1851,10 @@ void GetEmbedderOptions(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(ret); } -// This function returns a map containing all the options available -// as NODE_OPTIONS and their input type -// Example --experimental-transform types: kBoolean +// This function returns an object containing all the options available +// as NODE_OPTIONS and their metadata (input type and help text) +// Example --experimental-transform metadata: +// { type: kBoolean, help_text: "..." } // This is used to determine the type of the input for each option // to generate the config file json schema void GetEnvOptionsInputType(const FunctionCallbackInfo& args) { @@ -1839,23 +1870,31 @@ void GetEnvOptionsInputType(const FunctionCallbackInfo& args) { Mutex::ScopedLock lock(per_process::cli_options_mutex); - Local flags_map = Map::New(isolate); + Local options_metadata = Object::New(isolate); for (const auto& item : _ppop_instance.options_) { if (!item.first.empty() && !item.first.starts_with('[') && item.second.env_setting == kAllowedInEnvvar) { - if (!AddOptionTypeToMap( - isolate, context, flags_map, item.first, item.second.type)) { + const auto mapping_details = options_parser::OptionMappingDetails{ + item.second.type, + item.second.help_text, + }; + if (!AddOptionTypeToObject(isolate, + context, + options_metadata, + item.first, + mapping_details)) { return; } } } - args.GetReturnValue().Set(flags_map); + args.GetReturnValue().Set(options_metadata); } -// This function returns a two-level nested map containing all the available -// options grouped by their namespaces along with their input types. This is -// used for config file JSON schema generation +// This function returns a two-level nested map where: +// - Keys are namespace names (e.g., "testRunner") +// - Values are objects mapping option names to their metadata +// This is used for config file JSON schema generation void GetNamespaceOptionsInputType(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); Local context = isolate->GetCurrentContext(); @@ -1869,29 +1908,33 @@ void GetNamespaceOptionsInputType(const FunctionCallbackInfo& args) { Mutex::ScopedLock lock(per_process::cli_options_mutex); - Local namespaces_map = Map::New(isolate); + Local namespaces_metadata = Map::New(isolate); - // Get the mapping of namespaces to their options and types + // Get the mapping of namespaces to their options and metadata auto namespace_options = options_parser::MapNamespaceOptionsAssociations(); for (const auto& ns_entry : namespace_options) { const std::string& namespace_name = ns_entry.first; const auto& options_map = ns_entry.second; - Local options_type_map = Map::New(isolate); + Local options_metadata = Object::New(isolate); for (const auto& opt_entry : options_map) { const std::string& option_name = opt_entry.first; - const options_parser::OptionType& option_type = opt_entry.second; - - if (!AddOptionTypeToMap( - isolate, context, options_type_map, option_name, option_type)) { + const options_parser::OptionMappingDetails& option_details = + opt_entry.second; + + if (!AddOptionTypeToObject(isolate, + context, + options_metadata, + option_name, + option_details)) { return; } } // Only add namespaces that have options - if (options_type_map->Size() > 0) { + if (!options_metadata.IsEmpty()) { Local namespace_key; if (!String::NewFromUtf8(isolate, namespace_name.data(), @@ -1901,14 +1944,14 @@ void GetNamespaceOptionsInputType(const FunctionCallbackInfo& args) { continue; } - if (namespaces_map->Set(context, namespace_key, options_type_map) + if (namespaces_metadata->Set(context, namespace_key, options_metadata) .IsEmpty()) { return; } } } - args.GetReturnValue().Set(namespaces_map); + args.GetReturnValue().Set(namespaces_metadata); } // Return an array containing all currently active options as flag diff --git a/src/node_options.h b/src/node_options.h index 2d30c115dcb27e..9b59ffd7a542b0 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -404,11 +404,17 @@ enum OptionType { kHostPort, kStringList, }; -std::unordered_map MapEnvOptionsFlagInputType(); -std::unordered_map MapOptionsByNamespace( +struct OptionMappingDetails { + OptionType type; + std::string help_text; +}; +std::unordered_map +MapEnvOptionsFlagInputType(); +std::unordered_map MapOptionsByNamespace( std::string namespace_name); -std::unordered_map> +std::unordered_map< + std::string, + std::unordered_map> MapNamespaceOptionsAssociations(); std::vector MapAvailableNamespaces(); @@ -647,10 +653,10 @@ class OptionsParser { friend void GetCLIOptionsInfo( const v8::FunctionCallbackInfo& args); friend std::string GetBashCompletion(); - friend std::unordered_map + friend std::unordered_map MapEnvOptionsFlagInputType(); - friend std::unordered_map MapOptionsByNamespace( - std::string namespace_name); + friend std::unordered_map + MapOptionsByNamespace(std::string namespace_name); friend std::vector MapAvailableNamespaces(); friend void GetEnvOptionsInputType( const v8::FunctionCallbackInfo& args); diff --git a/test/parallel/test-config-json-schema.js b/test/parallel/test-config-json-schema.js index 1fbeb27a26848d..82679660a30feb 100644 --- a/test/parallel/test-config-json-schema.js +++ b/test/parallel/test-config-json-schema.js @@ -25,6 +25,14 @@ if (!common.hasQuic) { common.skip('this test requires QUIC'); } +if (process.config.variables.icu_small) { + common.skip('this test assumes full ICU build'); +} + +if (process.config.variables.node_quic) { + common.skip('this test assumes default configuration options'); +} + const { generateConfigJsonSchema, } = require('internal/options');