@optique/clack 1.3.0-dev.2467 → 1.3.0-dev.2469

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/index.cjs CHANGED
@@ -33,7 +33,8 @@ const defaultPromptFunctions = {
33
33
  confirm: __clack_prompts.confirm,
34
34
  select: __clack_prompts.select,
35
35
  multiselect: __clack_prompts.multiselect,
36
- isCancel: __clack_prompts.isCancel
36
+ isCancel: __clack_prompts.isCancel,
37
+ logError: (value) => __clack_prompts.log.error(value)
37
38
  };
38
39
  function promptFunctionKeys() {
39
40
  return Object.keys(defaultPromptFunctions);
@@ -60,45 +61,43 @@ function getPromptFunctions() {
60
61
  * @param parser Inner parser that reads CLI values.
61
62
  * @param config Type-safe Clack prompt configuration, or a configuration
62
63
  * derived from dependency sources via `derivePromptConfig()`.
64
+ * @param options Shared validation, retry, and cancellation options.
63
65
  * @returns A parser with interactive prompt fallback, always in async mode.
66
+ * @throws {RangeError} If `maxAttempts` is not a positive integer.
64
67
  * @throws {Error} If prompt execution fails with an unexpected error or if the
65
68
  * inner parser throws while parsing or completing.
66
69
  * @since 1.2.0
70
+ * @since 1.3.0 Added shared options and the prompter context.
67
71
  */
68
- function prompt(parser, config) {
72
+ function prompt(parser, config, options) {
69
73
  const promptWithAdapter = (0, __optique_prompt.createPromptAdapter)({
70
74
  execute: executePromptRaw,
71
75
  getDefaultValue: getConfigDefault
72
76
  });
73
- return promptWithAdapter(parser, config);
77
+ return promptWithAdapter(parser, config, options);
74
78
  }
75
79
  function getConfigDefault(config) {
76
80
  if (config != null && typeof config === "object" && "initialValue" in config) return config.initialValue;
77
81
  return void 0;
78
82
  }
79
- async function executePromptRaw(config) {
83
+ async function executePromptRaw(config, context) {
80
84
  const cfg = config;
81
85
  const type = cfg.type;
82
86
  if (!isPromptType(type)) throw new TypeError(`Unsupported prompt type: ${String(type)}.`);
83
87
  const prompts = getPromptFunctions();
84
- if ("prompter" in cfg && cfg.prompter != null) {
85
- const value = await cfg.prompter();
86
- if (prompts.isCancel(value)) return {
88
+ let result;
89
+ if ("prompter" in cfg && cfg.prompter != null) result = await cfg.prompter(context);
90
+ else {
91
+ if (context.previousValidationMessage !== void 0) prompts.logError((0, __optique_core_message.formatMessage)(context.previousValidationMessage));
92
+ result = await executeClackPromptWithSignal(cfg, prompts, context.signal);
93
+ }
94
+ if (prompts.isCancel(result)) {
95
+ if (context.signal?.aborted === true) throw context.signal.reason;
96
+ return {
87
97
  success: false,
88
98
  error: __optique_core_message.message`Prompt cancelled.`
89
99
  };
90
- if (cfg.type === "number") return normalizeNumberResult(value);
91
- if (cfg.type === "multiselect") return normalizeMultiselectResult(value, cfg);
92
- return {
93
- success: true,
94
- value
95
- };
96
100
  }
97
- const result = await executeClackPrompt(cfg, prompts);
98
- if (prompts.isCancel(result)) return {
99
- success: false,
100
- error: __optique_core_message.message`Prompt cancelled.`
101
- };
102
101
  if (cfg.type === "number") return normalizeNumberResult(result);
103
102
  if (cfg.type === "multiselect") return normalizeMultiselectResult(result, cfg);
104
103
  return {
@@ -106,28 +105,44 @@ async function executePromptRaw(config) {
106
105
  value: result
107
106
  };
108
107
  }
108
+ async function executeClackPromptWithSignal(cfg, prompts, signal) {
109
+ if (signal === void 0) return await executeClackPrompt(cfg, prompts);
110
+ const controller = new AbortController();
111
+ const abort = () => controller.abort(signal.reason);
112
+ if (signal.aborted) abort();
113
+ else signal.addEventListener("abort", abort, { once: true });
114
+ try {
115
+ return await executeClackPrompt(cfg, prompts, controller.signal);
116
+ } finally {
117
+ signal.removeEventListener("abort", abort);
118
+ }
119
+ }
109
120
  function isPromptType(value) {
110
121
  return value === "text" || value === "password" || value === "confirm" || value === "number" || value === "select" || value === "multiselect";
111
122
  }
112
- function executeClackPrompt(cfg, prompts) {
123
+ function executeClackPrompt(cfg, prompts, signal) {
113
124
  switch (cfg.type) {
114
125
  case "text": return prompts.text({
115
126
  message: cfg.message,
127
+ ...signal === void 0 ? {} : { signal },
116
128
  ...cfg.placeholder !== void 0 ? { placeholder: cfg.placeholder } : {},
117
129
  ...cfg.initialValue !== void 0 ? { initialValue: cfg.initialValue } : {},
118
130
  ...cfg.validate !== void 0 ? { validate: cfg.validate } : {}
119
131
  });
120
132
  case "password": return prompts.password({
121
133
  message: cfg.message,
134
+ ...signal === void 0 ? {} : { signal },
122
135
  ...cfg.mask !== void 0 ? { mask: cfg.mask } : {},
123
136
  ...cfg.validate !== void 0 ? { validate: cfg.validate } : {}
124
137
  });
125
138
  case "confirm": return prompts.confirm({
126
139
  message: cfg.message,
140
+ ...signal === void 0 ? {} : { signal },
127
141
  ...cfg.initialValue !== void 0 ? { initialValue: cfg.initialValue } : {}
128
142
  });
129
143
  case "number": return prompts.text({
130
144
  message: cfg.message,
145
+ ...signal === void 0 ? {} : { signal },
131
146
  ...cfg.placeholder !== void 0 ? { placeholder: cfg.placeholder } : {},
132
147
  ...cfg.initialValue !== void 0 ? { initialValue: String(cfg.initialValue) } : {},
133
148
  validate: async (value) => {
@@ -140,11 +155,13 @@ function executeClackPrompt(cfg, prompts) {
140
155
  });
141
156
  case "select": return prompts.select({
142
157
  message: cfg.message,
158
+ ...signal === void 0 ? {} : { signal },
143
159
  options: normalizeOptions(cfg.options),
144
160
  ...cfg.initialValue !== void 0 ? { initialValue: cfg.initialValue } : {}
145
161
  });
146
162
  case "multiselect": return prompts.multiselect({
147
163
  message: cfg.message,
164
+ ...signal === void 0 ? {} : { signal },
148
165
  options: normalizeOptions(cfg.options),
149
166
  ...cfg.required !== void 0 ? { required: cfg.required } : {}
150
167
  });
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { FluentParser } from "@optique/core/fluent";
2
2
  import { Mode, Parser } from "@optique/core/parser";
3
- import { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, DerivedPromptConfig as DerivedPromptConfig$1, PromptCondition, derivePromptConfig, isDerivedPromptConfig } from "@optique/prompt";
3
+ import { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, DerivedPromptConfig as DerivedPromptConfig$1, PromptCondition, PromptExecutionContext, PromptExecutionContext as PromptExecutionContext$1, PromptOptions, PromptOptions as PromptOptions$1, PromptValidator, derivePromptConfig, isDerivedPromptConfig } from "@optique/prompt";
4
4
 
5
5
  //#region src/index.d.ts
6
6
 
@@ -42,8 +42,11 @@ interface TextConfig {
42
42
  readonly initialValue?: string;
43
43
  /** Validation function called when the user submits. */
44
44
  readonly validate?: (value: string) => string | void | Promise<string | void>;
45
- /** Override the prompt execution. Useful for testing. */
46
- readonly prompter?: () => Promise<string>;
45
+ /**
46
+ * Overrides prompt execution. Useful for testing.
47
+ * @since 1.3.0 Added the execution context parameter.
48
+ */
49
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<string>;
47
50
  }
48
51
  /**
49
52
  * Configuration for a `password` prompt.
@@ -58,8 +61,11 @@ interface PasswordConfig {
58
61
  readonly mask?: string;
59
62
  /** Validation function called when the user submits. */
60
63
  readonly validate?: (value: string) => string | void | Promise<string | void>;
61
- /** Override the prompt execution. Useful for testing. */
62
- readonly prompter?: () => Promise<string>;
64
+ /**
65
+ * Overrides prompt execution. Useful for testing.
66
+ * @since 1.3.0 Added the execution context parameter.
67
+ */
68
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<string>;
63
69
  }
64
70
  /**
65
71
  * Configuration for a `confirm` prompt.
@@ -72,8 +78,11 @@ interface ConfirmConfig {
72
78
  readonly message: string;
73
79
  /** Initial Boolean value. */
74
80
  readonly initialValue?: boolean;
75
- /** Override the prompt execution. Useful for testing. */
76
- readonly prompter?: () => Promise<boolean>;
81
+ /**
82
+ * Overrides prompt execution. Useful for testing.
83
+ * @since 1.3.0 Added the execution context parameter.
84
+ */
85
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<boolean>;
77
86
  }
78
87
  /**
79
88
  * Configuration for a `number` prompt.
@@ -97,8 +106,11 @@ interface NumberPromptConfig {
97
106
  readonly max?: number;
98
107
  /** Additional validation after numeric conversion. */
99
108
  readonly validate?: (value: number) => string | void | Promise<string | void>;
100
- /** Override the prompt execution. Useful for testing. */
101
- readonly prompter?: () => Promise<number | undefined>;
109
+ /**
110
+ * Overrides prompt execution. Useful for testing.
111
+ * @since 1.3.0 Added the execution context parameter.
112
+ */
113
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<number | undefined>;
102
114
  }
103
115
  /**
104
116
  * Configuration for a `select` prompt.
@@ -113,8 +125,11 @@ interface SelectConfig {
113
125
  readonly options: readonly (string | Option)[];
114
126
  /** Initially selected option value. */
115
127
  readonly initialValue?: string;
116
- /** Override the prompt execution. Useful for testing. */
117
- readonly prompter?: () => Promise<string>;
128
+ /**
129
+ * Overrides prompt execution. Useful for testing.
130
+ * @since 1.3.0 Added the execution context parameter.
131
+ */
132
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<string>;
118
133
  }
119
134
  /**
120
135
  * Configuration for a `multiselect` prompt.
@@ -129,8 +144,11 @@ interface MultiselectConfig {
129
144
  readonly options: readonly (string | Option)[];
130
145
  /** Whether at least one option must be selected. */
131
146
  readonly required?: boolean;
132
- /** Override the prompt execution. Useful for testing. */
133
- readonly prompter?: () => Promise<readonly string[]>;
147
+ /**
148
+ * Overrides prompt execution. Useful for testing.
149
+ * @since 1.3.0 Added the execution context parameter.
150
+ */
151
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<readonly string[]>;
134
152
  }
135
153
  /**
136
154
  * A union of all string-valued prompt configurations.
@@ -164,11 +182,14 @@ type RuntimePromptConfig = ConfirmConfig | NumberPromptConfig | StringPromptConf
164
182
  * @param parser Inner parser that reads CLI values.
165
183
  * @param config Type-safe Clack prompt configuration, or a configuration
166
184
  * derived from dependency sources via `derivePromptConfig()`.
185
+ * @param options Shared validation, retry, and cancellation options.
167
186
  * @returns A parser with interactive prompt fallback, always in async mode.
187
+ * @throws {RangeError} If `maxAttempts` is not a positive integer.
168
188
  * @throws {Error} If prompt execution fails with an unexpected error or if the
169
189
  * inner parser throws while parsing or completing.
170
190
  * @since 1.2.0
191
+ * @since 1.3.0 Added shared options and the prompter context.
171
192
  */
172
- declare function prompt<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfig<TValue> | DerivedPromptConfig$1<RuntimePromptConfig, NoInfer<TValue>>): FluentParser<"async", TValue, TState>;
193
+ declare function prompt<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfig<TValue> | DerivedPromptConfig$1<RuntimePromptConfig, NoInfer<TValue>>, options?: PromptOptions$1<NoInfer<TValue>>): FluentParser<"async", TValue, TState>;
173
194
  //#endregion
174
- export { ConfirmConfig, type DerivePromptConfigContext, type DerivePromptConfigOptions, type DerivePromptConfigsContext, type DerivePromptConfigsOptions, type DerivedPromptConfig, MultiselectConfig, NumberPromptConfig, Option, PasswordConfig, PromptConfig, RuntimePromptConfig, SelectConfig, StringPromptConfig, TextConfig, derivePromptConfig, isDerivedPromptConfig, prompt };
195
+ export { ConfirmConfig, type DerivePromptConfigContext, type DerivePromptConfigOptions, type DerivePromptConfigsContext, type DerivePromptConfigsOptions, type DerivedPromptConfig, MultiselectConfig, NumberPromptConfig, Option, PasswordConfig, PromptConfig, type PromptExecutionContext, type PromptOptions, type PromptValidator, RuntimePromptConfig, SelectConfig, StringPromptConfig, TextConfig, derivePromptConfig, isDerivedPromptConfig, prompt };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, DerivedPromptConfig as DerivedPromptConfig$1, PromptCondition, derivePromptConfig, isDerivedPromptConfig } from "@optique/prompt";
1
+ import { DerivePromptConfigContext, DerivePromptConfigOptions, DerivePromptConfigsContext, DerivePromptConfigsOptions, DerivedPromptConfig, DerivedPromptConfig as DerivedPromptConfig$1, PromptCondition, PromptExecutionContext, PromptExecutionContext as PromptExecutionContext$1, PromptOptions, PromptOptions as PromptOptions$1, PromptValidator, derivePromptConfig, isDerivedPromptConfig } from "@optique/prompt";
2
2
  import { FluentParser } from "@optique/core/fluent";
3
3
  import { Mode, Parser } from "@optique/core/parser";
4
4
 
@@ -42,8 +42,11 @@ interface TextConfig {
42
42
  readonly initialValue?: string;
43
43
  /** Validation function called when the user submits. */
44
44
  readonly validate?: (value: string) => string | void | Promise<string | void>;
45
- /** Override the prompt execution. Useful for testing. */
46
- readonly prompter?: () => Promise<string>;
45
+ /**
46
+ * Overrides prompt execution. Useful for testing.
47
+ * @since 1.3.0 Added the execution context parameter.
48
+ */
49
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<string>;
47
50
  }
48
51
  /**
49
52
  * Configuration for a `password` prompt.
@@ -58,8 +61,11 @@ interface PasswordConfig {
58
61
  readonly mask?: string;
59
62
  /** Validation function called when the user submits. */
60
63
  readonly validate?: (value: string) => string | void | Promise<string | void>;
61
- /** Override the prompt execution. Useful for testing. */
62
- readonly prompter?: () => Promise<string>;
64
+ /**
65
+ * Overrides prompt execution. Useful for testing.
66
+ * @since 1.3.0 Added the execution context parameter.
67
+ */
68
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<string>;
63
69
  }
64
70
  /**
65
71
  * Configuration for a `confirm` prompt.
@@ -72,8 +78,11 @@ interface ConfirmConfig {
72
78
  readonly message: string;
73
79
  /** Initial Boolean value. */
74
80
  readonly initialValue?: boolean;
75
- /** Override the prompt execution. Useful for testing. */
76
- readonly prompter?: () => Promise<boolean>;
81
+ /**
82
+ * Overrides prompt execution. Useful for testing.
83
+ * @since 1.3.0 Added the execution context parameter.
84
+ */
85
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<boolean>;
77
86
  }
78
87
  /**
79
88
  * Configuration for a `number` prompt.
@@ -97,8 +106,11 @@ interface NumberPromptConfig {
97
106
  readonly max?: number;
98
107
  /** Additional validation after numeric conversion. */
99
108
  readonly validate?: (value: number) => string | void | Promise<string | void>;
100
- /** Override the prompt execution. Useful for testing. */
101
- readonly prompter?: () => Promise<number | undefined>;
109
+ /**
110
+ * Overrides prompt execution. Useful for testing.
111
+ * @since 1.3.0 Added the execution context parameter.
112
+ */
113
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<number | undefined>;
102
114
  }
103
115
  /**
104
116
  * Configuration for a `select` prompt.
@@ -113,8 +125,11 @@ interface SelectConfig {
113
125
  readonly options: readonly (string | Option)[];
114
126
  /** Initially selected option value. */
115
127
  readonly initialValue?: string;
116
- /** Override the prompt execution. Useful for testing. */
117
- readonly prompter?: () => Promise<string>;
128
+ /**
129
+ * Overrides prompt execution. Useful for testing.
130
+ * @since 1.3.0 Added the execution context parameter.
131
+ */
132
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<string>;
118
133
  }
119
134
  /**
120
135
  * Configuration for a `multiselect` prompt.
@@ -129,8 +144,11 @@ interface MultiselectConfig {
129
144
  readonly options: readonly (string | Option)[];
130
145
  /** Whether at least one option must be selected. */
131
146
  readonly required?: boolean;
132
- /** Override the prompt execution. Useful for testing. */
133
- readonly prompter?: () => Promise<readonly string[]>;
147
+ /**
148
+ * Overrides prompt execution. Useful for testing.
149
+ * @since 1.3.0 Added the execution context parameter.
150
+ */
151
+ readonly prompter?: (context: PromptExecutionContext$1) => Promise<readonly string[]>;
134
152
  }
135
153
  /**
136
154
  * A union of all string-valued prompt configurations.
@@ -164,11 +182,14 @@ type RuntimePromptConfig = ConfirmConfig | NumberPromptConfig | StringPromptConf
164
182
  * @param parser Inner parser that reads CLI values.
165
183
  * @param config Type-safe Clack prompt configuration, or a configuration
166
184
  * derived from dependency sources via `derivePromptConfig()`.
185
+ * @param options Shared validation, retry, and cancellation options.
167
186
  * @returns A parser with interactive prompt fallback, always in async mode.
187
+ * @throws {RangeError} If `maxAttempts` is not a positive integer.
168
188
  * @throws {Error} If prompt execution fails with an unexpected error or if the
169
189
  * inner parser throws while parsing or completing.
170
190
  * @since 1.2.0
191
+ * @since 1.3.0 Added shared options and the prompter context.
171
192
  */
172
- declare function prompt<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfig<TValue> | DerivedPromptConfig$1<RuntimePromptConfig, NoInfer<TValue>>): FluentParser<"async", TValue, TState>;
193
+ declare function prompt<M extends Mode, TValue, TState>(parser: Parser<M, TValue, TState>, config: PromptConfig<TValue> | DerivedPromptConfig$1<RuntimePromptConfig, NoInfer<TValue>>, options?: PromptOptions$1<NoInfer<TValue>>): FluentParser<"async", TValue, TState>;
173
194
  //#endregion
174
- export { ConfirmConfig, type DerivePromptConfigContext, type DerivePromptConfigOptions, type DerivePromptConfigsContext, type DerivePromptConfigsOptions, type DerivedPromptConfig, MultiselectConfig, NumberPromptConfig, Option, PasswordConfig, PromptConfig, RuntimePromptConfig, SelectConfig, StringPromptConfig, TextConfig, derivePromptConfig, isDerivedPromptConfig, prompt };
195
+ export { ConfirmConfig, type DerivePromptConfigContext, type DerivePromptConfigOptions, type DerivePromptConfigsContext, type DerivePromptConfigsOptions, type DerivedPromptConfig, MultiselectConfig, NumberPromptConfig, Option, PasswordConfig, PromptConfig, type PromptExecutionContext, type PromptOptions, type PromptValidator, RuntimePromptConfig, SelectConfig, StringPromptConfig, TextConfig, derivePromptConfig, isDerivedPromptConfig, prompt };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { confirm, isCancel, multiselect, password, select, text } from "@clack/prompts";
2
- import { message } from "@optique/core/message";
1
+ import { confirm, isCancel, log, multiselect, password, select, text } from "@clack/prompts";
2
+ import { formatMessage, message } from "@optique/core/message";
3
3
  import { createPromptAdapter, derivePromptConfig, isDerivedPromptConfig } from "@optique/prompt";
4
4
 
5
5
  //#region src/index.ts
@@ -10,7 +10,8 @@ const defaultPromptFunctions = {
10
10
  confirm,
11
11
  select,
12
12
  multiselect,
13
- isCancel
13
+ isCancel,
14
+ logError: (value) => log.error(value)
14
15
  };
15
16
  function promptFunctionKeys() {
16
17
  return Object.keys(defaultPromptFunctions);
@@ -37,45 +38,43 @@ function getPromptFunctions() {
37
38
  * @param parser Inner parser that reads CLI values.
38
39
  * @param config Type-safe Clack prompt configuration, or a configuration
39
40
  * derived from dependency sources via `derivePromptConfig()`.
41
+ * @param options Shared validation, retry, and cancellation options.
40
42
  * @returns A parser with interactive prompt fallback, always in async mode.
43
+ * @throws {RangeError} If `maxAttempts` is not a positive integer.
41
44
  * @throws {Error} If prompt execution fails with an unexpected error or if the
42
45
  * inner parser throws while parsing or completing.
43
46
  * @since 1.2.0
47
+ * @since 1.3.0 Added shared options and the prompter context.
44
48
  */
45
- function prompt(parser, config) {
49
+ function prompt(parser, config, options) {
46
50
  const promptWithAdapter = createPromptAdapter({
47
51
  execute: executePromptRaw,
48
52
  getDefaultValue: getConfigDefault
49
53
  });
50
- return promptWithAdapter(parser, config);
54
+ return promptWithAdapter(parser, config, options);
51
55
  }
52
56
  function getConfigDefault(config) {
53
57
  if (config != null && typeof config === "object" && "initialValue" in config) return config.initialValue;
54
58
  return void 0;
55
59
  }
56
- async function executePromptRaw(config) {
60
+ async function executePromptRaw(config, context) {
57
61
  const cfg = config;
58
62
  const type = cfg.type;
59
63
  if (!isPromptType(type)) throw new TypeError(`Unsupported prompt type: ${String(type)}.`);
60
64
  const prompts = getPromptFunctions();
61
- if ("prompter" in cfg && cfg.prompter != null) {
62
- const value = await cfg.prompter();
63
- if (prompts.isCancel(value)) return {
65
+ let result;
66
+ if ("prompter" in cfg && cfg.prompter != null) result = await cfg.prompter(context);
67
+ else {
68
+ if (context.previousValidationMessage !== void 0) prompts.logError(formatMessage(context.previousValidationMessage));
69
+ result = await executeClackPromptWithSignal(cfg, prompts, context.signal);
70
+ }
71
+ if (prompts.isCancel(result)) {
72
+ if (context.signal?.aborted === true) throw context.signal.reason;
73
+ return {
64
74
  success: false,
65
75
  error: message`Prompt cancelled.`
66
76
  };
67
- if (cfg.type === "number") return normalizeNumberResult(value);
68
- if (cfg.type === "multiselect") return normalizeMultiselectResult(value, cfg);
69
- return {
70
- success: true,
71
- value
72
- };
73
77
  }
74
- const result = await executeClackPrompt(cfg, prompts);
75
- if (prompts.isCancel(result)) return {
76
- success: false,
77
- error: message`Prompt cancelled.`
78
- };
79
78
  if (cfg.type === "number") return normalizeNumberResult(result);
80
79
  if (cfg.type === "multiselect") return normalizeMultiselectResult(result, cfg);
81
80
  return {
@@ -83,28 +82,44 @@ async function executePromptRaw(config) {
83
82
  value: result
84
83
  };
85
84
  }
85
+ async function executeClackPromptWithSignal(cfg, prompts, signal) {
86
+ if (signal === void 0) return await executeClackPrompt(cfg, prompts);
87
+ const controller = new AbortController();
88
+ const abort = () => controller.abort(signal.reason);
89
+ if (signal.aborted) abort();
90
+ else signal.addEventListener("abort", abort, { once: true });
91
+ try {
92
+ return await executeClackPrompt(cfg, prompts, controller.signal);
93
+ } finally {
94
+ signal.removeEventListener("abort", abort);
95
+ }
96
+ }
86
97
  function isPromptType(value) {
87
98
  return value === "text" || value === "password" || value === "confirm" || value === "number" || value === "select" || value === "multiselect";
88
99
  }
89
- function executeClackPrompt(cfg, prompts) {
100
+ function executeClackPrompt(cfg, prompts, signal) {
90
101
  switch (cfg.type) {
91
102
  case "text": return prompts.text({
92
103
  message: cfg.message,
104
+ ...signal === void 0 ? {} : { signal },
93
105
  ...cfg.placeholder !== void 0 ? { placeholder: cfg.placeholder } : {},
94
106
  ...cfg.initialValue !== void 0 ? { initialValue: cfg.initialValue } : {},
95
107
  ...cfg.validate !== void 0 ? { validate: cfg.validate } : {}
96
108
  });
97
109
  case "password": return prompts.password({
98
110
  message: cfg.message,
111
+ ...signal === void 0 ? {} : { signal },
99
112
  ...cfg.mask !== void 0 ? { mask: cfg.mask } : {},
100
113
  ...cfg.validate !== void 0 ? { validate: cfg.validate } : {}
101
114
  });
102
115
  case "confirm": return prompts.confirm({
103
116
  message: cfg.message,
117
+ ...signal === void 0 ? {} : { signal },
104
118
  ...cfg.initialValue !== void 0 ? { initialValue: cfg.initialValue } : {}
105
119
  });
106
120
  case "number": return prompts.text({
107
121
  message: cfg.message,
122
+ ...signal === void 0 ? {} : { signal },
108
123
  ...cfg.placeholder !== void 0 ? { placeholder: cfg.placeholder } : {},
109
124
  ...cfg.initialValue !== void 0 ? { initialValue: String(cfg.initialValue) } : {},
110
125
  validate: async (value) => {
@@ -117,11 +132,13 @@ function executeClackPrompt(cfg, prompts) {
117
132
  });
118
133
  case "select": return prompts.select({
119
134
  message: cfg.message,
135
+ ...signal === void 0 ? {} : { signal },
120
136
  options: normalizeOptions(cfg.options),
121
137
  ...cfg.initialValue !== void 0 ? { initialValue: cfg.initialValue } : {}
122
138
  });
123
139
  case "multiselect": return prompts.multiselect({
124
140
  message: cfg.message,
141
+ ...signal === void 0 ? {} : { signal },
125
142
  options: normalizeOptions(cfg.options),
126
143
  ...cfg.required !== void 0 ? { required: cfg.required } : {}
127
144
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/clack",
3
- "version": "1.3.0-dev.2467",
3
+ "version": "1.3.0-dev.2469",
4
4
  "description": "Interactive prompt support for Optique via Clack",
5
5
  "keywords": [
6
6
  "CLI",
@@ -62,12 +62,12 @@
62
62
  "sideEffects": false,
63
63
  "dependencies": {
64
64
  "@clack/prompts": "^1.6.0",
65
- "@optique/core": "1.3.0-dev.2467+17bce761",
66
- "@optique/prompt": "1.3.0-dev.2467+17bce761"
65
+ "@optique/core": "1.3.0-dev.2469+77a16530",
66
+ "@optique/prompt": "1.3.0-dev.2469+77a16530"
67
67
  },
68
68
  "devDependencies": {
69
- "@optique/env": "1.3.0-dev.2467+17bce761",
70
- "@optique/run": "1.3.0-dev.2467+17bce761",
69
+ "@optique/env": "1.3.0-dev.2469+77a16530",
70
+ "@optique/run": "1.3.0-dev.2469+77a16530",
71
71
  "@types/node": "^24.0.0",
72
72
  "fast-check": "^4.7.0",
73
73
  "tsdown": "^0.13.0",