@optique/run 1.3.0-dev.2559 → 1.3.0-dev.2563

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/run.cjs CHANGED
@@ -1,4 +1,5 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_terminal = require('./terminal.cjs');
2
3
  const __optique_core_facade = require_rolldown_runtime.__toESM(require("@optique/core/facade"));
3
4
  const node_path = require_rolldown_runtime.__toESM(require("node:path"));
4
5
  const node_process = require_rolldown_runtime.__toESM(require("node:process"));
@@ -72,8 +73,8 @@ function buildCoreOptions(options, programMetadata) {
72
73
  node_process.default.stderr.write(`${line}\n`);
73
74
  });
74
75
  const onExit = options.onExit ?? ((exitCode) => node_process.default.exit(exitCode));
75
- const colors = options.colors ?? node_process.default.stdout.isTTY;
76
- const maxWidth = options.maxWidth ?? node_process.default.stdout.columns;
76
+ const colors = options.colors ?? require_terminal.detectColorSupport(node_process.default.stdout, require_terminal.readEnvironmentVariable);
77
+ const maxWidth = options.maxWidth ?? require_terminal.detectTerminalWidth(node_process.default.stdout, require_terminal.readEnvironmentVariable);
77
78
  const termWidth = options.termWidth;
78
79
  const showDefault = options.showDefault;
79
80
  const showChoices = options.showChoices;
package/dist/run.d.cts CHANGED
@@ -53,14 +53,22 @@ interface RunOptions {
53
53
  /**
54
54
  * Whether to enable colored output in help and error messages.
55
55
  *
56
- * @default `process.stdout.isTTY` (auto-detect based on terminal)
56
+ * Explicit values override environment variables and terminal detection.
57
+ * A nonempty `FORCE_COLOR` enables colors (including `0`); otherwise a
58
+ * nonempty `NO_COLOR` or any `NODE_DISABLE_COLORS` disables them.
59
+ * Inaccessible environment variables are ignored.
60
+ *
61
+ * @default Environment preferences, then `process.stdout.isTTY`
57
62
  */
58
63
  readonly colors?: boolean;
59
64
  /**
60
65
  * Maximum width for output formatting. Text will be wrapped to fit within
61
- * this width. If not specified, uses the terminal width.
66
+ * this width. If not specified, uses a positive finite integer from the
67
+ * terminal width, then a positive decimal integer from `COLUMNS`. Invalid
68
+ * or inaccessible detected values are ignored; explicit values retain the
69
+ * formatter's validation.
62
70
  *
63
- * @default `process.stdout.columns` (auto-detect terminal width)
71
+ * @default Valid `process.stdout.columns`, then `COLUMNS`, or no wrapping
64
72
  */
65
73
  readonly maxWidth?: number;
66
74
  /**
package/dist/run.d.ts CHANGED
@@ -53,14 +53,22 @@ interface RunOptions {
53
53
  /**
54
54
  * Whether to enable colored output in help and error messages.
55
55
  *
56
- * @default `process.stdout.isTTY` (auto-detect based on terminal)
56
+ * Explicit values override environment variables and terminal detection.
57
+ * A nonempty `FORCE_COLOR` enables colors (including `0`); otherwise a
58
+ * nonempty `NO_COLOR` or any `NODE_DISABLE_COLORS` disables them.
59
+ * Inaccessible environment variables are ignored.
60
+ *
61
+ * @default Environment preferences, then `process.stdout.isTTY`
57
62
  */
58
63
  readonly colors?: boolean;
59
64
  /**
60
65
  * Maximum width for output formatting. Text will be wrapped to fit within
61
- * this width. If not specified, uses the terminal width.
66
+ * this width. If not specified, uses a positive finite integer from the
67
+ * terminal width, then a positive decimal integer from `COLUMNS`. Invalid
68
+ * or inaccessible detected values are ignored; explicit values retain the
69
+ * formatter's validation.
62
70
  *
63
- * @default `process.stdout.columns` (auto-detect terminal width)
71
+ * @default Valid `process.stdout.columns`, then `COLUMNS`, or no wrapping
64
72
  */
65
73
  readonly maxWidth?: number;
66
74
  /**
package/dist/run.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { detectColorSupport, detectTerminalWidth, readEnvironmentVariable } from "./terminal.js";
1
2
  import { runParser, runWith, runWithSync } from "@optique/core/facade";
2
3
  import path from "node:path";
3
4
  import process from "node:process";
@@ -71,8 +72,8 @@ function buildCoreOptions(options, programMetadata) {
71
72
  process.stderr.write(`${line}\n`);
72
73
  });
73
74
  const onExit = options.onExit ?? ((exitCode) => process.exit(exitCode));
74
- const colors = options.colors ?? process.stdout.isTTY;
75
- const maxWidth = options.maxWidth ?? process.stdout.columns;
75
+ const colors = options.colors ?? detectColorSupport(process.stdout, readEnvironmentVariable);
76
+ const maxWidth = options.maxWidth ?? detectTerminalWidth(process.stdout, readEnvironmentVariable);
76
77
  const termWidth = options.termWidth;
77
78
  const showDefault = options.showDefault;
78
79
  const showChoices = options.showChoices;
@@ -0,0 +1,59 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const node_process = require_rolldown_runtime.__toESM(require("node:process"));
3
+
4
+ //#region src/terminal.ts
5
+ /**
6
+ * Resolves automatic color settings without changing the supplied environment.
7
+ * @param stream The output stream's TTY status.
8
+ * @param readEnv Reads one environment variable at a time.
9
+ * @returns The color preference, preserving an unspecified TTY fallback.
10
+ * @internal
11
+ */
12
+ function detectColorSupport(stream, readEnv) {
13
+ const forceColor = readEnv("FORCE_COLOR");
14
+ if (forceColor != null && forceColor !== "") return true;
15
+ const noColor = readEnv("NO_COLOR");
16
+ if (noColor != null && noColor !== "") return false;
17
+ if (readEnv("NODE_DISABLE_COLORS") != null) return false;
18
+ return stream.isTTY;
19
+ }
20
+ /**
21
+ * Resolves a usable reported width, leaving unknown widths unwrapped.
22
+ * @param stream The output stream's reported width.
23
+ * @param readEnv Reads COLUMNS if the stream has no valid width.
24
+ * @returns A positive finite integer, or undefined when neither source is valid.
25
+ * @internal
26
+ */
27
+ function detectTerminalWidth(stream, readEnv) {
28
+ const columns = stream.columns;
29
+ if (columns != null && Number.isInteger(columns) && columns > 0) return columns;
30
+ const value = readEnv("COLUMNS");
31
+ if (value == null || value === "" || /[^0-9]/u.test(value)) return void 0;
32
+ const width = Number(value);
33
+ return Number.isInteger(width) && width > 0 ? width : void 0;
34
+ }
35
+ /**
36
+ * Reads an optional terminal setting without requesting runtime permissions.
37
+ * @param name The environment variable to read.
38
+ * @returns Its value, or undefined when absent or inaccessible.
39
+ * @internal
40
+ */
41
+ function readEnvironmentVariable(name) {
42
+ try {
43
+ if (name === "NODE_DISABLE_COLORS" || name === "COLUMNS") {
44
+ const deno = globalThis.Deno;
45
+ if (deno != null && deno.permissions?.querySync?.({
46
+ name: "env",
47
+ variable: name
48
+ }).state !== "granted") return void 0;
49
+ }
50
+ return node_process.default.env[name];
51
+ } catch {
52
+ return void 0;
53
+ }
54
+ }
55
+
56
+ //#endregion
57
+ exports.detectColorSupport = detectColorSupport;
58
+ exports.detectTerminalWidth = detectTerminalWidth;
59
+ exports.readEnvironmentVariable = readEnvironmentVariable;
@@ -0,0 +1,56 @@
1
+ import process from "node:process";
2
+
3
+ //#region src/terminal.ts
4
+ /**
5
+ * Resolves automatic color settings without changing the supplied environment.
6
+ * @param stream The output stream's TTY status.
7
+ * @param readEnv Reads one environment variable at a time.
8
+ * @returns The color preference, preserving an unspecified TTY fallback.
9
+ * @internal
10
+ */
11
+ function detectColorSupport(stream, readEnv) {
12
+ const forceColor = readEnv("FORCE_COLOR");
13
+ if (forceColor != null && forceColor !== "") return true;
14
+ const noColor = readEnv("NO_COLOR");
15
+ if (noColor != null && noColor !== "") return false;
16
+ if (readEnv("NODE_DISABLE_COLORS") != null) return false;
17
+ return stream.isTTY;
18
+ }
19
+ /**
20
+ * Resolves a usable reported width, leaving unknown widths unwrapped.
21
+ * @param stream The output stream's reported width.
22
+ * @param readEnv Reads COLUMNS if the stream has no valid width.
23
+ * @returns A positive finite integer, or undefined when neither source is valid.
24
+ * @internal
25
+ */
26
+ function detectTerminalWidth(stream, readEnv) {
27
+ const columns = stream.columns;
28
+ if (columns != null && Number.isInteger(columns) && columns > 0) return columns;
29
+ const value = readEnv("COLUMNS");
30
+ if (value == null || value === "" || /[^0-9]/u.test(value)) return void 0;
31
+ const width = Number(value);
32
+ return Number.isInteger(width) && width > 0 ? width : void 0;
33
+ }
34
+ /**
35
+ * Reads an optional terminal setting without requesting runtime permissions.
36
+ * @param name The environment variable to read.
37
+ * @returns Its value, or undefined when absent or inaccessible.
38
+ * @internal
39
+ */
40
+ function readEnvironmentVariable(name) {
41
+ try {
42
+ if (name === "NODE_DISABLE_COLORS" || name === "COLUMNS") {
43
+ const deno = globalThis.Deno;
44
+ if (deno != null && deno.permissions?.querySync?.({
45
+ name: "env",
46
+ variable: name
47
+ }).state !== "granted") return void 0;
48
+ }
49
+ return process.env[name];
50
+ } catch {
51
+ return void 0;
52
+ }
53
+ }
54
+
55
+ //#endregion
56
+ export { detectColorSupport, detectTerminalWidth, readEnvironmentVariable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/run",
3
- "version": "1.3.0-dev.2559",
3
+ "version": "1.3.0-dev.2563",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",
@@ -76,11 +76,11 @@
76
76
  },
77
77
  "sideEffects": false,
78
78
  "dependencies": {
79
- "@optique/core": "1.3.0-dev.2559+02079a47"
79
+ "@optique/core": "1.3.0-dev.2563+56de9f1b"
80
80
  },
81
81
  "devDependencies": {
82
- "@optique/config": "1.3.0-dev.2559+02079a47",
83
- "@optique/env": "1.3.0-dev.2559+02079a47",
82
+ "@optique/config": "1.3.0-dev.2563+56de9f1b",
83
+ "@optique/env": "1.3.0-dev.2563+56de9f1b",
84
84
  "@types/node": "^24.0.0",
85
85
  "fast-check": "^4.7.0",
86
86
  "tsdown": "^0.13.0",