@optique/core 0.5.0-dev.63 → 0.5.0-dev.65

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/doc.cjs CHANGED
@@ -81,7 +81,10 @@ function formatDocPage(programName, page, options = {}) {
81
81
  if (options.showDefault && entry.default != null) {
82
82
  const prefix = typeof options.showDefault === "object" ? options.showDefault.prefix ?? " [" : " [";
83
83
  const suffix = typeof options.showDefault === "object" ? options.showDefault.suffix ?? "]" : "]";
84
- const defaultText = `${prefix}${entry.default}${suffix}`;
84
+ const defaultText = `${prefix}${require_message.formatMessage(entry.default, {
85
+ colors: options.colors ? { resetSuffix: "\x1B[2m" } : false,
86
+ quotes: !options.colors
87
+ })}${suffix}`;
85
88
  const formattedDefault = options.colors ? `\x1b[2m${defaultText}\x1b[0m` : defaultText;
86
89
  description += formattedDefault;
87
90
  }
package/dist/doc.d.cts CHANGED
@@ -24,7 +24,7 @@ interface DocEntry {
24
24
  * indicate what the default behavior is if the command or option is not
25
25
  * specified.
26
26
  */
27
- readonly default?: string;
27
+ readonly default?: Message;
28
28
  }
29
29
  /**
30
30
  * A section in a document that groups related entries together.
package/dist/doc.d.ts CHANGED
@@ -24,7 +24,7 @@ interface DocEntry {
24
24
  * indicate what the default behavior is if the command or option is not
25
25
  * specified.
26
26
  */
27
- readonly default?: string;
27
+ readonly default?: Message;
28
28
  }
29
29
  /**
30
30
  * A section in a document that groups related entries together.
package/dist/doc.js CHANGED
@@ -81,7 +81,10 @@ function formatDocPage(programName, page, options = {}) {
81
81
  if (options.showDefault && entry.default != null) {
82
82
  const prefix = typeof options.showDefault === "object" ? options.showDefault.prefix ?? " [" : " [";
83
83
  const suffix = typeof options.showDefault === "object" ? options.showDefault.suffix ?? "]" : "]";
84
- const defaultText = `${prefix}${entry.default}${suffix}`;
84
+ const defaultText = `${prefix}${formatMessage(entry.default, {
85
+ colors: options.colors ? { resetSuffix: "\x1B[2m" } : false,
86
+ quotes: !options.colors
87
+ })}${suffix}`;
85
88
  const formattedDefault = options.colors ? `\x1b[2m${defaultText}\x1b[0m` : defaultText;
86
89
  description += formattedDefault;
87
90
  }
package/dist/index.cjs CHANGED
@@ -12,6 +12,7 @@ exports.choice = require_valueparser.choice;
12
12
  exports.command = require_parser.command;
13
13
  exports.concat = require_parser.concat;
14
14
  exports.constant = require_parser.constant;
15
+ exports.envVar = require_message.envVar;
15
16
  exports.flag = require_parser.flag;
16
17
  exports.float = require_valueparser.float;
17
18
  exports.formatDocPage = require_doc.formatDocPage;
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- import { Message, MessageFormatOptions, MessageTerm, formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.cjs";
1
+ import { Message, MessageFormatOptions, MessageTerm, envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.cjs";
2
2
  import { OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.cjs";
3
3
  import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowDefaultOptions, formatDocPage } from "./doc.cjs";
4
4
  import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.cjs";
5
- import { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.cjs";
5
+ import { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.cjs";
6
6
  import { RunError, RunOptions, run } from "./facade.cjs";
7
- export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShowDefaultOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, argument, choice, command, concat, constant, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
7
+ export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShowDefaultOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, choice, command, concat, constant, envVar, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Message, MessageFormatOptions, MessageTerm, formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.js";
1
+ import { Message, MessageFormatOptions, MessageTerm, envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.js";
2
2
  import { OptionName, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
3
3
  import { DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, ShowDefaultOptions, formatDocPage } from "./doc.js";
4
4
  import { ChoiceOptions, FloatOptions, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, StringOptions, UrlOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
5
- import { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
5
+ import { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
6
6
  import { RunError, RunOptions, run } from "./facade.js";
7
- export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShowDefaultOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, argument, choice, command, concat, constant, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
7
+ export { ArgumentOptions, ChoiceOptions, CommandOptions, DocEntry, DocFragment, DocFragments, DocPage, DocPageFormatOptions, DocSection, DocState, FlagOptions, FloatOptions, InferValue, IntegerOptionsBigInt, IntegerOptionsNumber, LocaleOptions, Message, MessageFormatOptions, MessageTerm, MultipleOptions, OptionName, OptionOptions, Parser, ParserContext, ParserResult, Result, RunError, RunOptions, ShowDefaultOptions, StringOptions, UrlOptions, Usage, UsageFormatOptions, UsageTerm, UsageTermFormatOptions, Uuid, UuidOptions, ValueParser, ValueParserResult, WithDefaultError, WithDefaultOptions, argument, choice, command, concat, constant, envVar, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.js";
1
+ import { envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values } from "./message.js";
2
2
  import { formatUsage, formatUsageTerm, normalizeUsage } from "./usage.js";
3
3
  import { formatDocPage } from "./doc.js";
4
4
  import { choice, float, integer, isValueParser, locale, string, url, uuid } from "./valueparser.js";
5
5
  import { WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault } from "./parser.js";
6
6
  import { RunError, run } from "./facade.js";
7
7
 
8
- export { RunError, WithDefaultError, argument, choice, command, concat, constant, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
8
+ export { RunError, WithDefaultError, argument, choice, command, concat, constant, envVar, flag, float, formatDocPage, formatMessage, formatUsage, formatUsageTerm, getDocPage, group, integer, isValueParser, locale, longestMatch, map, merge, message, metavar, multiple, normalizeUsage, object, option, optionName, optionNames, optional, or, parse, run, string, text, tuple, url, uuid, value, values, withDefault };
package/dist/message.cjs CHANGED
@@ -113,6 +113,19 @@ function values(values$1) {
113
113
  };
114
114
  }
115
115
  /**
116
+ * Creates a {@link MessageTerm} for an environment variable.
117
+ * @param envVar The environment variable name, which is a string that represents
118
+ * an environment variable. For example, `"PATH"` or `"API_URL"`.
119
+ * @returns A {@link MessageTerm} representing the environment variable.
120
+ * @since 0.5.0
121
+ */
122
+ function envVar(envVar$1) {
123
+ return {
124
+ type: "envVar",
125
+ envVar: envVar$1
126
+ };
127
+ }
128
+ /**
116
129
  * Formats a {@link Message} into a human-readable string for
117
130
  * the terminal.
118
131
  * @param msg The message to format, which is an array of
@@ -121,8 +134,11 @@ function values(values$1) {
121
134
  * @returns A formatted string representation of the message.
122
135
  */
123
136
  function formatMessage(msg, options = {}) {
124
- const useColors = options.colors ?? false;
137
+ const colorConfig = options.colors ?? false;
138
+ const useColors = typeof colorConfig === "boolean" ? colorConfig : true;
139
+ const resetSuffix = typeof colorConfig === "object" ? colorConfig.resetSuffix ?? "" : "";
125
140
  const useQuotes = options.quotes ?? true;
141
+ const resetSequence = `\x1b[0m${resetSuffix}`;
126
142
  function* stream() {
127
143
  const wordPattern = /\s*\S+\s*/g;
128
144
  for (const term of msg) if (term.type === "text") while (true) {
@@ -136,7 +152,7 @@ function formatMessage(msg, options = {}) {
136
152
  else if (term.type === "optionName") {
137
153
  const name = useQuotes ? `\`${term.optionName}\`` : term.optionName;
138
154
  yield {
139
- text: useColors ? `\x1b[3m${name}\x1b[0m` : name,
155
+ text: useColors ? `\x1b[3m${name}${resetSequence}` : name,
140
156
  width: name.length
141
157
  };
142
158
  } else if (term.type === "optionNames") {
@@ -148,7 +164,7 @@ function formatMessage(msg, options = {}) {
148
164
  width: 1
149
165
  };
150
166
  yield {
151
- text: useColors ? `\x1b[3m${name}\x1b[0m` : name,
167
+ text: useColors ? `\x1b[3m${name}${resetSequence}` : name,
152
168
  width: name.length
153
169
  };
154
170
  i++;
@@ -156,13 +172,13 @@ function formatMessage(msg, options = {}) {
156
172
  } else if (term.type === "metavar") {
157
173
  const metavar$1 = useQuotes ? `\`${term.metavar}\`` : term.metavar;
158
174
  yield {
159
- text: useColors ? `\x1b[1m${metavar$1}\x1b[0m` : metavar$1,
175
+ text: useColors ? `\x1b[1m${metavar$1}${resetSequence}` : metavar$1,
160
176
  width: metavar$1.length
161
177
  };
162
178
  } else if (term.type === "value") {
163
179
  const value$1 = useQuotes ? `${JSON.stringify(term.value)}` : term.value;
164
180
  yield {
165
- text: useColors ? `\x1b[32m${value$1}\x1b[0m` : value$1,
181
+ text: useColors ? `\x1b[32m${value$1}${resetSequence}` : value$1,
166
182
  width: value$1.length
167
183
  };
168
184
  } else if (term.type === "values") for (let i = 0; i < term.values.length; i++) {
@@ -172,11 +188,17 @@ function formatMessage(msg, options = {}) {
172
188
  };
173
189
  const value$1 = useQuotes ? JSON.stringify(term.values[i]) : term.values[i];
174
190
  yield {
175
- text: useColors ? i <= 0 ? `\x1b[32m${value$1}` : i + 1 >= term.values.length ? `${value$1}\x1b[0m` : value$1 : value$1,
191
+ text: useColors ? i <= 0 ? `\x1b[32m${value$1}` : i + 1 >= term.values.length ? `${value$1}${resetSequence}` : value$1 : value$1,
176
192
  width: value$1.length
177
193
  };
178
194
  }
179
- else throw new TypeError(`Invalid MessageTerm type: ${term["type"]}.`);
195
+ else if (term.type === "envVar") {
196
+ const envVar$1 = useQuotes ? `\`${term.envVar}\`` : term.envVar;
197
+ yield {
198
+ text: useColors ? `\x1b[1;4m${envVar$1}${resetSequence}` : envVar$1,
199
+ width: envVar$1.length
200
+ };
201
+ } else throw new TypeError(`Invalid MessageTerm type: ${term["type"]}.`);
180
202
  }
181
203
  let output = "";
182
204
  let totalWidth = 0;
@@ -192,6 +214,7 @@ function formatMessage(msg, options = {}) {
192
214
  }
193
215
 
194
216
  //#endregion
217
+ exports.envVar = envVar;
195
218
  exports.formatMessage = formatMessage;
196
219
  exports.message = message;
197
220
  exports.metavar = metavar;
@@ -89,6 +89,21 @@ type MessageTerm =
89
89
  * representations of consecutive values. For example, `["42", "hello"]`.
90
90
  */
91
91
  readonly values: readonly string[];
92
+ }
93
+ /**
94
+ * An environment variable term in the message, which represents
95
+ * an environment variable name.
96
+ * @since 0.5.0
97
+ */ | {
98
+ /**
99
+ * The type of the term, which is `"envVar"` for an environment variable.
100
+ */
101
+ readonly type: "envVar";
102
+ /**
103
+ * The environment variable name, which is a string that represents
104
+ * an environment variable. For example, `"PATH"` or `"API_URL"`.
105
+ */
106
+ readonly envVar: string;
92
107
  };
93
108
  /**
94
109
  * Type representing a message that can include styled/colored values.
@@ -160,6 +175,14 @@ declare function value(value: string): MessageTerm;
160
175
  * @returns A {@link MessageTerm} representing the list of values.
161
176
  */
162
177
  declare function values(values: readonly string[]): MessageTerm;
178
+ /**
179
+ * Creates a {@link MessageTerm} for an environment variable.
180
+ * @param envVar The environment variable name, which is a string that represents
181
+ * an environment variable. For example, `"PATH"` or `"API_URL"`.
182
+ * @returns A {@link MessageTerm} representing the environment variable.
183
+ * @since 0.5.0
184
+ */
185
+ declare function envVar(envVar: string): MessageTerm;
163
186
  /**
164
187
  * Options for the {@link formatMessage} function.
165
188
  */
@@ -168,9 +191,21 @@ interface MessageFormatOptions {
168
191
  * Whether to use colors in the formatted message. If `true`,
169
192
  * the formatted message will include ANSI escape codes for colors.
170
193
  * If `false`, the message will be plain text without colors.
194
+ *
195
+ * Can also be an object with additional color options:
196
+ *
197
+ * - `resetSuffix`: String to append after each ANSI reset sequence (`\x1b[0m`)
198
+ * to maintain parent styling context.
199
+ *
171
200
  * @default `false`
172
201
  */
173
- readonly colors?: boolean;
202
+ readonly colors?: boolean | {
203
+ /**
204
+ * String to append after each ANSI reset sequence to maintain
205
+ * parent styling context (e.g., `"\x1b[2m"` for dim text).
206
+ */
207
+ readonly resetSuffix?: string;
208
+ };
174
209
  /**
175
210
  * Whether to use quotes around values in the formatted message.
176
211
  * If `true`, values will be wrapped in quotes (e.g., `"value"`).
@@ -196,4 +231,4 @@ interface MessageFormatOptions {
196
231
  */
197
232
  declare function formatMessage(msg: Message, options?: MessageFormatOptions): string;
198
233
  //#endregion
199
- export { Message, MessageFormatOptions, MessageTerm, formatMessage, message, metavar, optionName, optionNames, text, value, values };
234
+ export { Message, MessageFormatOptions, MessageTerm, envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values };
package/dist/message.d.ts CHANGED
@@ -89,6 +89,21 @@ type MessageTerm =
89
89
  * representations of consecutive values. For example, `["42", "hello"]`.
90
90
  */
91
91
  readonly values: readonly string[];
92
+ }
93
+ /**
94
+ * An environment variable term in the message, which represents
95
+ * an environment variable name.
96
+ * @since 0.5.0
97
+ */ | {
98
+ /**
99
+ * The type of the term, which is `"envVar"` for an environment variable.
100
+ */
101
+ readonly type: "envVar";
102
+ /**
103
+ * The environment variable name, which is a string that represents
104
+ * an environment variable. For example, `"PATH"` or `"API_URL"`.
105
+ */
106
+ readonly envVar: string;
92
107
  };
93
108
  /**
94
109
  * Type representing a message that can include styled/colored values.
@@ -160,6 +175,14 @@ declare function value(value: string): MessageTerm;
160
175
  * @returns A {@link MessageTerm} representing the list of values.
161
176
  */
162
177
  declare function values(values: readonly string[]): MessageTerm;
178
+ /**
179
+ * Creates a {@link MessageTerm} for an environment variable.
180
+ * @param envVar The environment variable name, which is a string that represents
181
+ * an environment variable. For example, `"PATH"` or `"API_URL"`.
182
+ * @returns A {@link MessageTerm} representing the environment variable.
183
+ * @since 0.5.0
184
+ */
185
+ declare function envVar(envVar: string): MessageTerm;
163
186
  /**
164
187
  * Options for the {@link formatMessage} function.
165
188
  */
@@ -168,9 +191,21 @@ interface MessageFormatOptions {
168
191
  * Whether to use colors in the formatted message. If `true`,
169
192
  * the formatted message will include ANSI escape codes for colors.
170
193
  * If `false`, the message will be plain text without colors.
194
+ *
195
+ * Can also be an object with additional color options:
196
+ *
197
+ * - `resetSuffix`: String to append after each ANSI reset sequence (`\x1b[0m`)
198
+ * to maintain parent styling context.
199
+ *
171
200
  * @default `false`
172
201
  */
173
- readonly colors?: boolean;
202
+ readonly colors?: boolean | {
203
+ /**
204
+ * String to append after each ANSI reset sequence to maintain
205
+ * parent styling context (e.g., `"\x1b[2m"` for dim text).
206
+ */
207
+ readonly resetSuffix?: string;
208
+ };
174
209
  /**
175
210
  * Whether to use quotes around values in the formatted message.
176
211
  * If `true`, values will be wrapped in quotes (e.g., `"value"`).
@@ -196,4 +231,4 @@ interface MessageFormatOptions {
196
231
  */
197
232
  declare function formatMessage(msg: Message, options?: MessageFormatOptions): string;
198
233
  //#endregion
199
- export { Message, MessageFormatOptions, MessageTerm, formatMessage, message, metavar, optionName, optionNames, text, value, values };
234
+ export { Message, MessageFormatOptions, MessageTerm, envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values };
package/dist/message.js CHANGED
@@ -112,6 +112,19 @@ function values(values$1) {
112
112
  };
113
113
  }
114
114
  /**
115
+ * Creates a {@link MessageTerm} for an environment variable.
116
+ * @param envVar The environment variable name, which is a string that represents
117
+ * an environment variable. For example, `"PATH"` or `"API_URL"`.
118
+ * @returns A {@link MessageTerm} representing the environment variable.
119
+ * @since 0.5.0
120
+ */
121
+ function envVar(envVar$1) {
122
+ return {
123
+ type: "envVar",
124
+ envVar: envVar$1
125
+ };
126
+ }
127
+ /**
115
128
  * Formats a {@link Message} into a human-readable string for
116
129
  * the terminal.
117
130
  * @param msg The message to format, which is an array of
@@ -120,8 +133,11 @@ function values(values$1) {
120
133
  * @returns A formatted string representation of the message.
121
134
  */
122
135
  function formatMessage(msg, options = {}) {
123
- const useColors = options.colors ?? false;
136
+ const colorConfig = options.colors ?? false;
137
+ const useColors = typeof colorConfig === "boolean" ? colorConfig : true;
138
+ const resetSuffix = typeof colorConfig === "object" ? colorConfig.resetSuffix ?? "" : "";
124
139
  const useQuotes = options.quotes ?? true;
140
+ const resetSequence = `\x1b[0m${resetSuffix}`;
125
141
  function* stream() {
126
142
  const wordPattern = /\s*\S+\s*/g;
127
143
  for (const term of msg) if (term.type === "text") while (true) {
@@ -135,7 +151,7 @@ function formatMessage(msg, options = {}) {
135
151
  else if (term.type === "optionName") {
136
152
  const name = useQuotes ? `\`${term.optionName}\`` : term.optionName;
137
153
  yield {
138
- text: useColors ? `\x1b[3m${name}\x1b[0m` : name,
154
+ text: useColors ? `\x1b[3m${name}${resetSequence}` : name,
139
155
  width: name.length
140
156
  };
141
157
  } else if (term.type === "optionNames") {
@@ -147,7 +163,7 @@ function formatMessage(msg, options = {}) {
147
163
  width: 1
148
164
  };
149
165
  yield {
150
- text: useColors ? `\x1b[3m${name}\x1b[0m` : name,
166
+ text: useColors ? `\x1b[3m${name}${resetSequence}` : name,
151
167
  width: name.length
152
168
  };
153
169
  i++;
@@ -155,13 +171,13 @@ function formatMessage(msg, options = {}) {
155
171
  } else if (term.type === "metavar") {
156
172
  const metavar$1 = useQuotes ? `\`${term.metavar}\`` : term.metavar;
157
173
  yield {
158
- text: useColors ? `\x1b[1m${metavar$1}\x1b[0m` : metavar$1,
174
+ text: useColors ? `\x1b[1m${metavar$1}${resetSequence}` : metavar$1,
159
175
  width: metavar$1.length
160
176
  };
161
177
  } else if (term.type === "value") {
162
178
  const value$1 = useQuotes ? `${JSON.stringify(term.value)}` : term.value;
163
179
  yield {
164
- text: useColors ? `\x1b[32m${value$1}\x1b[0m` : value$1,
180
+ text: useColors ? `\x1b[32m${value$1}${resetSequence}` : value$1,
165
181
  width: value$1.length
166
182
  };
167
183
  } else if (term.type === "values") for (let i = 0; i < term.values.length; i++) {
@@ -171,11 +187,17 @@ function formatMessage(msg, options = {}) {
171
187
  };
172
188
  const value$1 = useQuotes ? JSON.stringify(term.values[i]) : term.values[i];
173
189
  yield {
174
- text: useColors ? i <= 0 ? `\x1b[32m${value$1}` : i + 1 >= term.values.length ? `${value$1}\x1b[0m` : value$1 : value$1,
190
+ text: useColors ? i <= 0 ? `\x1b[32m${value$1}` : i + 1 >= term.values.length ? `${value$1}${resetSequence}` : value$1 : value$1,
175
191
  width: value$1.length
176
192
  };
177
193
  }
178
- else throw new TypeError(`Invalid MessageTerm type: ${term["type"]}.`);
194
+ else if (term.type === "envVar") {
195
+ const envVar$1 = useQuotes ? `\`${term.envVar}\`` : term.envVar;
196
+ yield {
197
+ text: useColors ? `\x1b[1;4m${envVar$1}${resetSequence}` : envVar$1,
198
+ width: envVar$1.length
199
+ };
200
+ } else throw new TypeError(`Invalid MessageTerm type: ${term["type"]}.`);
179
201
  }
180
202
  let output = "";
181
203
  let totalWidth = 0;
@@ -191,4 +213,4 @@ function formatMessage(msg, options = {}) {
191
213
  }
192
214
 
193
215
  //#endregion
194
- export { formatMessage, message, metavar, optionName, optionNames, text, value, values };
216
+ export { envVar, formatMessage, message, metavar, optionName, optionNames, text, value, values };
package/dist/parser.cjs CHANGED
@@ -209,7 +209,7 @@ function option(...args) {
209
209
  metavar: valueParser?.metavar
210
210
  },
211
211
  description: options.description,
212
- default: defaultValue != null && valueParser != null ? valueParser.format(defaultValue) : void 0
212
+ default: defaultValue != null && valueParser != null ? require_message.message`${valueParser.format(defaultValue)}` : void 0
213
213
  }];
214
214
  return {
215
215
  fragments,
@@ -458,7 +458,7 @@ function argument(valueParser, options = {}) {
458
458
  type: "entry",
459
459
  term,
460
460
  description: options.description,
461
- default: defaultValue == null ? void 0 : valueParser.format(defaultValue)
461
+ default: defaultValue == null ? void 0 : require_message.message`${valueParser.format(defaultValue)}`
462
462
  }];
463
463
  return {
464
464
  fragments,
@@ -532,7 +532,7 @@ function optional(parser) {
532
532
  * withDefault(option("--url", url()), () => {
533
533
  * if (!process.env.INSTANCE_URL) {
534
534
  * throw new WithDefaultError(
535
- * message`Environment variable ${text("INSTANCE_URL")} is not set.`
535
+ * message`Environment variable ${envVar("INSTANCE_URL")} is not set.`
536
536
  * );
537
537
  * }
538
538
  * return new URL(process.env.INSTANCE_URL);
@@ -556,22 +556,7 @@ var WithDefaultError = class extends Error {
556
556
  this.name = "WithDefaultError";
557
557
  }
558
558
  };
559
- /**
560
- * Creates a parser that makes another parser use a default value when it fails
561
- * to match or consume input. This is similar to {@link optional}, but instead
562
- * of returning `undefined` when the wrapped parser doesn't match, it returns
563
- * a specified default value.
564
- * @template TValue The type of the value returned by the wrapped parser.
565
- * @template TState The type of the state used by the wrapped parser.
566
- * @template TDefault The type of the default value.
567
- * @param parser The {@link Parser} to wrap with default behavior.
568
- * @param defaultValue The default value to return when the wrapped parser
569
- * doesn't match or consume input. Can be a value of type
570
- * {@link TDefault} or a function that returns such a value.
571
- * @returns A {@link Parser} that produces either the result of the wrapped parser
572
- * or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
573
- */
574
- function withDefault(parser, defaultValue) {
559
+ function withDefault(parser, defaultValue, options) {
575
560
  return {
576
561
  $valueType: [],
577
562
  $stateType: [],
@@ -616,7 +601,22 @@ function withDefault(parser, defaultValue) {
616
601
  kind: "available",
617
602
  state: state.state[0]
618
603
  };
619
- return parser.getDocFragments(innerState, upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue);
604
+ const actualDefaultValue = upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue;
605
+ const fragments = parser.getDocFragments(innerState, actualDefaultValue);
606
+ if (options?.message) {
607
+ const modifiedFragments = fragments.fragments.map((fragment) => {
608
+ if (fragment.type === "entry") return {
609
+ ...fragment,
610
+ default: options.message
611
+ };
612
+ return fragment;
613
+ });
614
+ return {
615
+ ...fragments,
616
+ fragments: modifiedFragments
617
+ };
618
+ }
619
+ return fragments;
620
620
  }
621
621
  };
622
622
  }
package/dist/parser.d.cts CHANGED
@@ -276,6 +276,26 @@ declare function argument<T>(valueParser: ValueParser<T>, options?: ArgumentOpti
276
276
  * or `undefined` if the wrapped parser fails to match.
277
277
  */
278
278
  declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parser<TValue | undefined, [TState] | undefined>;
279
+ /**
280
+ * Options for the {@link withDefault} parser.
281
+ */
282
+ interface WithDefaultOptions {
283
+ /**
284
+ * Custom message to display in help output instead of the formatted default value.
285
+ * This allows showing descriptive text like "SERVICE_URL environment variable"
286
+ * instead of the actual default value.
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * withDefault(
291
+ * option("--url", url()),
292
+ * process.env["SERVICE_URL"],
293
+ * { message: message`${envVar("SERVICE_URL")} environment variable` }
294
+ * )
295
+ * ```
296
+ */
297
+ readonly message?: Message;
298
+ }
279
299
  /**
280
300
  * Error type for structured error messages in {@link withDefault} default value callbacks.
281
301
  * Unlike regular errors that only support string messages, this error type accepts
@@ -286,7 +306,7 @@ declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parse
286
306
  * withDefault(option("--url", url()), () => {
287
307
  * if (!process.env.INSTANCE_URL) {
288
308
  * throw new WithDefaultError(
289
- * message`Environment variable ${text("INSTANCE_URL")} is not set.`
309
+ * message`Environment variable ${envVar("INSTANCE_URL")} is not set.`
290
310
  * );
291
311
  * }
292
312
  * return new URL(process.env.INSTANCE_URL);
@@ -319,9 +339,29 @@ declare class WithDefaultError extends Error {
319
339
  * doesn't match or consume input. Can be a value of type
320
340
  * {@link TDefault} or a function that returns such a value.
321
341
  * @returns A {@link Parser} that produces either the result of the wrapped parser
322
- * or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
342
+ * or the default value if the wrapped parser fails to match
343
+ * (union type {@link TValue} | {@link TDefault}).
323
344
  */
324
345
  declare function withDefault<TValue, TState, TDefault = TValue>(parser: Parser<TValue, TState>, defaultValue: TDefault | (() => TDefault)): Parser<TValue | TDefault, [TState] | undefined>;
346
+ /**
347
+ * Creates a parser that makes another parser use a default value when it fails
348
+ * to match or consume input. This is similar to {@link optional}, but instead
349
+ * of returning `undefined` when the wrapped parser doesn't match, it returns
350
+ * a specified default value.
351
+ * @template TValue The type of the value returned by the wrapped parser.
352
+ * @template TState The type of the state used by the wrapped parser.
353
+ * @template TDefault The type of the default value.
354
+ * @param parser The {@link Parser} to wrap with default behavior.
355
+ * @param defaultValue The default value to return when the wrapped parser
356
+ * doesn't match or consume input. Can be a value of type
357
+ * {@link TDefault} or a function that returns such a value.
358
+ * @param options Optional configuration including custom help display message.
359
+ * @returns A {@link Parser} that produces either the result of the wrapped parser
360
+ * or the default value if the wrapped parser fails to match
361
+ * (union type {@link TValue} | {@link TDefault}).
362
+ * @since 0.5.0
363
+ */
364
+ declare function withDefault<TValue, TState, TDefault = TValue>(parser: Parser<TValue, TState>, defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): Parser<TValue | TDefault, [TState] | undefined>;
325
365
  /**
326
366
  * Creates a parser that transforms the result value of another parser using
327
367
  * a mapping function. This enables value transformation while preserving
@@ -1461,4 +1501,4 @@ declare function group<TValue, TState>(label: string, parser: Parser<TValue, TSt
1461
1501
  */
1462
1502
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
1463
1503
  //#endregion
1464
- export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
1504
+ export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
package/dist/parser.d.ts CHANGED
@@ -276,6 +276,26 @@ declare function argument<T>(valueParser: ValueParser<T>, options?: ArgumentOpti
276
276
  * or `undefined` if the wrapped parser fails to match.
277
277
  */
278
278
  declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parser<TValue | undefined, [TState] | undefined>;
279
+ /**
280
+ * Options for the {@link withDefault} parser.
281
+ */
282
+ interface WithDefaultOptions {
283
+ /**
284
+ * Custom message to display in help output instead of the formatted default value.
285
+ * This allows showing descriptive text like "SERVICE_URL environment variable"
286
+ * instead of the actual default value.
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * withDefault(
291
+ * option("--url", url()),
292
+ * process.env["SERVICE_URL"],
293
+ * { message: message`${envVar("SERVICE_URL")} environment variable` }
294
+ * )
295
+ * ```
296
+ */
297
+ readonly message?: Message;
298
+ }
279
299
  /**
280
300
  * Error type for structured error messages in {@link withDefault} default value callbacks.
281
301
  * Unlike regular errors that only support string messages, this error type accepts
@@ -286,7 +306,7 @@ declare function optional<TValue, TState>(parser: Parser<TValue, TState>): Parse
286
306
  * withDefault(option("--url", url()), () => {
287
307
  * if (!process.env.INSTANCE_URL) {
288
308
  * throw new WithDefaultError(
289
- * message`Environment variable ${text("INSTANCE_URL")} is not set.`
309
+ * message`Environment variable ${envVar("INSTANCE_URL")} is not set.`
290
310
  * );
291
311
  * }
292
312
  * return new URL(process.env.INSTANCE_URL);
@@ -319,9 +339,29 @@ declare class WithDefaultError extends Error {
319
339
  * doesn't match or consume input. Can be a value of type
320
340
  * {@link TDefault} or a function that returns such a value.
321
341
  * @returns A {@link Parser} that produces either the result of the wrapped parser
322
- * or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
342
+ * or the default value if the wrapped parser fails to match
343
+ * (union type {@link TValue} | {@link TDefault}).
323
344
  */
324
345
  declare function withDefault<TValue, TState, TDefault = TValue>(parser: Parser<TValue, TState>, defaultValue: TDefault | (() => TDefault)): Parser<TValue | TDefault, [TState] | undefined>;
346
+ /**
347
+ * Creates a parser that makes another parser use a default value when it fails
348
+ * to match or consume input. This is similar to {@link optional}, but instead
349
+ * of returning `undefined` when the wrapped parser doesn't match, it returns
350
+ * a specified default value.
351
+ * @template TValue The type of the value returned by the wrapped parser.
352
+ * @template TState The type of the state used by the wrapped parser.
353
+ * @template TDefault The type of the default value.
354
+ * @param parser The {@link Parser} to wrap with default behavior.
355
+ * @param defaultValue The default value to return when the wrapped parser
356
+ * doesn't match or consume input. Can be a value of type
357
+ * {@link TDefault} or a function that returns such a value.
358
+ * @param options Optional configuration including custom help display message.
359
+ * @returns A {@link Parser} that produces either the result of the wrapped parser
360
+ * or the default value if the wrapped parser fails to match
361
+ * (union type {@link TValue} | {@link TDefault}).
362
+ * @since 0.5.0
363
+ */
364
+ declare function withDefault<TValue, TState, TDefault = TValue>(parser: Parser<TValue, TState>, defaultValue: TDefault | (() => TDefault), options?: WithDefaultOptions): Parser<TValue | TDefault, [TState] | undefined>;
325
365
  /**
326
366
  * Creates a parser that transforms the result value of another parser using
327
367
  * a mapping function. This enables value transformation while preserving
@@ -1461,4 +1501,4 @@ declare function group<TValue, TState>(label: string, parser: Parser<TValue, TSt
1461
1501
  */
1462
1502
  declare function getDocPage(parser: Parser<unknown, unknown>, args?: readonly string[]): DocPage | undefined;
1463
1503
  //#endregion
1464
- export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
1504
+ export { ArgumentOptions, CommandOptions, DocState, FlagOptions, InferValue, MultipleOptions, OptionOptions, Parser, ParserContext, ParserResult, Result, WithDefaultError, WithDefaultOptions, argument, command, concat, constant, flag, getDocPage, group, longestMatch, map, merge, multiple, object, option, optional, or, parse, tuple, withDefault };
package/dist/parser.js CHANGED
@@ -209,7 +209,7 @@ function option(...args) {
209
209
  metavar: valueParser?.metavar
210
210
  },
211
211
  description: options.description,
212
- default: defaultValue != null && valueParser != null ? valueParser.format(defaultValue) : void 0
212
+ default: defaultValue != null && valueParser != null ? message`${valueParser.format(defaultValue)}` : void 0
213
213
  }];
214
214
  return {
215
215
  fragments,
@@ -458,7 +458,7 @@ function argument(valueParser, options = {}) {
458
458
  type: "entry",
459
459
  term,
460
460
  description: options.description,
461
- default: defaultValue == null ? void 0 : valueParser.format(defaultValue)
461
+ default: defaultValue == null ? void 0 : message`${valueParser.format(defaultValue)}`
462
462
  }];
463
463
  return {
464
464
  fragments,
@@ -532,7 +532,7 @@ function optional(parser) {
532
532
  * withDefault(option("--url", url()), () => {
533
533
  * if (!process.env.INSTANCE_URL) {
534
534
  * throw new WithDefaultError(
535
- * message`Environment variable ${text("INSTANCE_URL")} is not set.`
535
+ * message`Environment variable ${envVar("INSTANCE_URL")} is not set.`
536
536
  * );
537
537
  * }
538
538
  * return new URL(process.env.INSTANCE_URL);
@@ -556,22 +556,7 @@ var WithDefaultError = class extends Error {
556
556
  this.name = "WithDefaultError";
557
557
  }
558
558
  };
559
- /**
560
- * Creates a parser that makes another parser use a default value when it fails
561
- * to match or consume input. This is similar to {@link optional}, but instead
562
- * of returning `undefined` when the wrapped parser doesn't match, it returns
563
- * a specified default value.
564
- * @template TValue The type of the value returned by the wrapped parser.
565
- * @template TState The type of the state used by the wrapped parser.
566
- * @template TDefault The type of the default value.
567
- * @param parser The {@link Parser} to wrap with default behavior.
568
- * @param defaultValue The default value to return when the wrapped parser
569
- * doesn't match or consume input. Can be a value of type
570
- * {@link TDefault} or a function that returns such a value.
571
- * @returns A {@link Parser} that produces either the result of the wrapped parser
572
- * or the default value if the wrapped parser fails to match (union type {@link TValue} | {@link TDefault}).
573
- */
574
- function withDefault(parser, defaultValue) {
559
+ function withDefault(parser, defaultValue, options) {
575
560
  return {
576
561
  $valueType: [],
577
562
  $stateType: [],
@@ -616,7 +601,22 @@ function withDefault(parser, defaultValue) {
616
601
  kind: "available",
617
602
  state: state.state[0]
618
603
  };
619
- return parser.getDocFragments(innerState, upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue);
604
+ const actualDefaultValue = upperDefaultValue != null ? upperDefaultValue : typeof defaultValue === "function" ? defaultValue() : defaultValue;
605
+ const fragments = parser.getDocFragments(innerState, actualDefaultValue);
606
+ if (options?.message) {
607
+ const modifiedFragments = fragments.fragments.map((fragment) => {
608
+ if (fragment.type === "entry") return {
609
+ ...fragment,
610
+ default: options.message
611
+ };
612
+ return fragment;
613
+ });
614
+ return {
615
+ ...fragments,
616
+ fragments: modifiedFragments
617
+ };
618
+ }
619
+ return fragments;
620
620
  }
621
621
  };
622
622
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "0.5.0-dev.63+48ac6884",
3
+ "version": "0.5.0-dev.65+6fcdf2be",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",