@depup/inquirer 13.4.0-depup.0 → 14.0.2-depup.23

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/README.md CHANGED
@@ -13,10 +13,16 @@ npm install @depup/inquirer
13
13
 
14
14
  | Field | Value |
15
15
  |-------|-------|
16
- | Original | [inquirer](https://www.npmjs.com/package/inquirer) @ 13.4.0 |
17
- | Processed | 2026-04-06 |
16
+ | Original | [inquirer](https://www.npmjs.com/package/inquirer) @ 14.0.2 |
17
+ | Processed | 2026-07-21 |
18
18
  | Smoke test | passed |
19
- | Deps updated | 0 |
19
+ | Deps updated | 1 |
20
+
21
+ ## Dependency Changes
22
+
23
+ | Dependency | From | To |
24
+ |------------|------|-----|
25
+ | mute-stream | ^3.0.0 | ^4.0.0 |
20
26
 
21
27
  ---
22
28
 
package/changes.json CHANGED
@@ -1,5 +1,10 @@
1
1
  {
2
- "bumped": {},
3
- "timestamp": "2026-04-06T20:24:20.370Z",
4
- "totalUpdated": 0
2
+ "bumped": {
3
+ "mute-stream": {
4
+ "from": "^3.0.0",
5
+ "to": "^4.0.0"
6
+ }
7
+ },
8
+ "timestamp": "2026-07-21T17:16:42.865Z",
9
+ "totalUpdated": 1
5
10
  }
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { checkbox, confirm, editor, expand, input, number, password, rawlist, search, select } from '@inquirer/prompts';
2
2
  import type { Context, DistributiveMerge, Prettify } from '@inquirer/type';
3
- import { Observable } from 'rxjs';
3
+ import type { Observable } from './utils/observable.ts';
4
4
  export type Answers<Key extends string = string> = Record<Key, any>;
5
5
  export type NoInfer<T> = [T][T extends any ? 0 : never];
6
6
  type UnionToIntersection<U> = (U extends unknown ? (arg: U) => void : never) extends (arg: infer I) => void ? I : never;
@@ -47,7 +47,7 @@ export interface QuestionMap {
47
47
  }
48
48
  type KeyValueOrAsyncGetterFunction<T, k extends string, A extends Answers> = T extends Record<string, any> ? MaybeAsyncValue<T[k], A> : never;
49
49
  export type Question<A extends Answers = Answers, Type extends string = string> = {
50
- type: Type;
50
+ type?: Type;
51
51
  name: string;
52
52
  message: MaybeAsyncValue<string, A>;
53
53
  default?: any;
@@ -85,7 +85,7 @@ export type QuestionDictionary<A extends Answers, Q> = {
85
85
  };
86
86
  export type DictionaryAnswers<A extends Answers, Prefilled extends Answers> = MergeAnswerObjects<NormalizeAnswers<Answers<Extract<keyof A, string>>>, WidenAnswerLiterals<Prefilled>>;
87
87
  export type PromptModulePublicQuestion<A extends Answers, Flat extends Answers = A> = {
88
- type: 'input' | 'confirm' | 'editor' | 'password' | 'number' | 'rawlist' | 'expand' | 'checkbox' | 'search' | 'select';
88
+ type?: 'input' | 'confirm' | 'editor' | 'password' | 'number' | 'rawlist' | 'expand' | 'checkbox' | 'search' | 'select';
89
89
  name: Extract<keyof Flat, string>;
90
90
  message: MaybeAsyncValue<string, A>;
91
91
  default?: unknown;
@@ -1,6 +1,6 @@
1
- import { Observable } from 'rxjs';
2
1
  import type { InquirerReadline } from '@inquirer/type';
3
2
  import type { Answers, PromptSession, StreamOptions } from '../types.ts';
3
+ import type { InteropObservable } from '../utils/observable.ts';
4
4
  export declare const _: {
5
5
  set: (obj: Record<string, unknown>, path: string | undefined, value: unknown) => void;
6
6
  get: (obj: object, path?: string | number | symbol, defaultValue?: unknown) => any;
@@ -39,17 +39,22 @@ export type PromptFn<Value = any, Config = any> = (config: Config, context: Stre
39
39
  * Provides a set of prompt-constructors.
40
40
  */
41
41
  export type PromptCollection = Record<string, PromptFn | LegacyPromptConstructor>;
42
+ type AnswerEvent = {
43
+ name: string;
44
+ answer: unknown;
45
+ };
42
46
  /**
43
47
  * Base interface class other can inherits from
44
48
  */
45
49
  export default class PromptsRunner<A extends Answers> {
46
50
  private prompts;
47
51
  answers: Partial<A>;
48
- process: Observable<any>;
52
+ process: InteropObservable<AnswerEvent>;
49
53
  private abortController;
50
54
  private opt;
51
55
  constructor(prompts: PromptCollection, opt?: StreamOptions);
52
56
  run(questions: PromptSession<A>, answers?: Partial<A>): Promise<A>;
57
+ private getQuestions;
53
58
  private prepareQuestion;
54
59
  private fetchAnswer;
55
60
  /**
@@ -58,3 +63,4 @@ export default class PromptsRunner<A extends Answers> {
58
63
  close: () => void;
59
64
  private shouldRun;
60
65
  }
66
+ export {};
package/dist/ui/prompt.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */
2
2
  import readline from 'node:readline';
3
- import { defer, EMPTY, from, of, concatMap, filter, reduce, isObservable, lastValueFrom, } from 'rxjs';
4
3
  import runAsync from 'run-async';
5
4
  import MuteStream from 'mute-stream';
6
5
  import { AbortPromptError } from '@inquirer/core';
7
6
  import { cursorShow } from '@inquirer/ansi';
7
+ import { EMPTY, createObservableController, isObservableLike, observableToAsyncIterable, } from "../utils/observable.js";
8
8
  export const _ = {
9
9
  set: (obj, path = '', value) => {
10
10
  let pointer = obj;
@@ -45,6 +45,13 @@ async function fetchAsyncQuestionProperty(question, prop, answers) {
45
45
  // oxlint-disable-next-line typescript/no-unsafe-type-assertion
46
46
  return propGetter;
47
47
  }
48
+ class UnknownPromptTypeError extends Error {
49
+ name = 'UnknownPromptTypeError';
50
+ constructor(type, prompts) {
51
+ const availableTypes = Object.keys(prompts).toSorted().join(', ');
52
+ super(`Prompt type "${type}" is not registered. Available prompt types: ${availableTypes}`);
53
+ }
54
+ }
48
55
  class TTYError extends Error {
49
56
  name = 'TTYError';
50
57
  isTtyError = true;
@@ -101,40 +108,53 @@ export default class PromptsRunner {
101
108
  }
102
109
  async run(questions, answers) {
103
110
  this.abortController = new AbortController();
111
+ const processController = createObservableController();
112
+ this.process = processController.observable;
104
113
  // Keep global reference to the answers
105
114
  this.answers = typeof answers === 'object' ? { ...answers } : {};
106
- let obs;
115
+ try {
116
+ for await (const question of this.getQuestions(questions)) {
117
+ if (await this.shouldRun(question)) {
118
+ const answer = await this.fetchAnswer(question);
119
+ _.set(this.answers, answer.name, answer.answer);
120
+ processController.next(answer);
121
+ }
122
+ }
123
+ processController.complete();
124
+ // oxlint-disable-next-line typescript/no-unsafe-type-assertion
125
+ return this.answers;
126
+ }
127
+ catch (error) {
128
+ processController.error(error);
129
+ throw error;
130
+ }
131
+ finally {
132
+ this.close();
133
+ }
134
+ }
135
+ async *getQuestions(questions) {
107
136
  if (isQuestionArray(questions)) {
108
- obs = from(questions);
137
+ yield* questions;
109
138
  }
110
- else if (isObservable(questions)) {
111
- obs = questions;
139
+ else if (isObservableLike(questions)) {
140
+ yield* observableToAsyncIterable(questions);
112
141
  }
113
142
  else if (isQuestionMap(questions)) {
114
143
  // Case: Called with a set of { name: question }
115
- obs = from(Object.entries(questions).map(([name, question]) => {
116
- return Object.assign({}, question, { name });
117
- }));
144
+ for (const [name, question] of Object.entries(questions)) {
145
+ yield Object.assign({}, question, { name });
146
+ }
118
147
  }
119
148
  else {
120
149
  // Case: Called with a single question config
121
- obs = from([questions]);
150
+ yield questions;
122
151
  }
123
- this.process = obs.pipe(concatMap((question) => of(question).pipe(concatMap((question) => from(this.shouldRun(question).then((shouldRun) => {
124
- if (shouldRun) {
125
- return question;
126
- }
127
- return;
128
- })).pipe(filter((val) => val != null))), concatMap((question) => defer(() => from(this.fetchAnswer(question)))))));
129
- return (lastValueFrom(this.process.pipe(reduce((answersObj, answer) => {
130
- _.set(answersObj, answer.name, answer.answer);
131
- return answersObj;
132
- }, this.answers)))
133
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
134
- .then(() => this.answers)
135
- .finally(() => this.close()));
136
152
  }
137
153
  prepareQuestion = async (question) => {
154
+ const type = question.type ?? 'input';
155
+ if (!Object.hasOwn(this.prompts, type)) {
156
+ throw new UnknownPromptTypeError(type, this.prompts);
157
+ }
138
158
  const [message, defaultValue, resolvedChoices] = await Promise.all([
139
159
  fetchAsyncQuestionProperty(question, 'message', this.answers),
140
160
  fetchAsyncQuestionProperty(question, 'default', this.answers),
@@ -168,7 +188,7 @@ export default class PromptsRunner {
168
188
  message,
169
189
  default: defaultValue,
170
190
  choices,
171
- type: question.type in this.prompts ? question.type : 'input',
191
+ type,
172
192
  });
173
193
  if (question.validate) {
174
194
  const originalValidate = question.validate;
@@ -208,6 +228,11 @@ export default class PromptsRunner {
208
228
  rl.setPrompt('');
209
229
  rl.output.unmute();
210
230
  rl.output.write(cursorShow);
231
+ // Reset cursor to column 0. On Windows terminals, \n moves the
232
+ // cursor down without resetting the column when the rendered
233
+ // prompt+answer wraps past the terminal width. Without this,
234
+ // all subsequent output starts at the wrong horizontal offset.
235
+ readline.cursorTo(rl.output, 0);
211
236
  rl.output.end();
212
237
  rl.close();
213
238
  };
@@ -0,0 +1,39 @@
1
+ type NextHandler<T> = (value: T) => void;
2
+ type ErrorHandler = (error: unknown) => void;
3
+ type CompleteHandler = () => void;
4
+ declare global {
5
+ interface SymbolConstructor {
6
+ readonly observable: symbol;
7
+ }
8
+ }
9
+ export type Observer<T> = {
10
+ next?: NextHandler<T>;
11
+ error?: ErrorHandler;
12
+ complete?: CompleteHandler;
13
+ };
14
+ export type SubscriptionLike = {
15
+ closed?: boolean;
16
+ unsubscribe: () => void;
17
+ };
18
+ export type Observable<T> = {
19
+ subscribe: {
20
+ (observer: Observer<T>): SubscriptionLike;
21
+ (next?: NextHandler<T> | null, error?: ErrorHandler | null, complete?: CompleteHandler | null): SubscriptionLike;
22
+ };
23
+ };
24
+ export type InteropObservable<T> = Observable<T> & AsyncIterable<T> & {
25
+ readonly [Symbol.observable]: () => Observable<T>;
26
+ readonly '@@observable': () => Observable<T>;
27
+ };
28
+ type ObservableController<T> = {
29
+ observable: InteropObservable<T>;
30
+ next: (value: T) => void;
31
+ error: (error: unknown) => void;
32
+ complete: () => void;
33
+ };
34
+ export declare const EMPTY: InteropObservable<never>;
35
+ export declare function createObservableController<T>(): ObservableController<T>;
36
+ type ObservableValue<T> = T extends Observable<infer Value> ? Value : never;
37
+ export declare function isObservableLike<T>(value: T): value is T & Observable<ObservableValue<T>>;
38
+ export declare function observableToAsyncIterable<T>(source: Observable<T>): AsyncIterable<T>;
39
+ export {};
@@ -0,0 +1,282 @@
1
+ function getObservableSymbol() {
2
+ const symbolConstructor = Symbol;
3
+ return typeof symbolConstructor.observable === 'symbol'
4
+ ? symbolConstructor.observable
5
+ : '@@observable';
6
+ }
7
+ function normalizeObserver(observerOrNext, error, complete) {
8
+ if (typeof observerOrNext === 'function') {
9
+ return {
10
+ next: observerOrNext,
11
+ ...(error ? { error } : {}),
12
+ ...(complete ? { complete } : {}),
13
+ };
14
+ }
15
+ return observerOrNext ?? {};
16
+ }
17
+ function reportObserverError(error) {
18
+ queueMicrotask(() => {
19
+ throw error;
20
+ });
21
+ }
22
+ function callObserver(callback) {
23
+ try {
24
+ callback();
25
+ }
26
+ catch (error) {
27
+ reportObserverError(error);
28
+ }
29
+ }
30
+ function createClosedSubscription() {
31
+ return {
32
+ closed: true,
33
+ unsubscribe() { },
34
+ };
35
+ }
36
+ function toError(error) {
37
+ return error instanceof Error ? error : new Error(String(error));
38
+ }
39
+ function runTeardown(teardown) {
40
+ if (typeof teardown === 'function') {
41
+ teardown();
42
+ }
43
+ else {
44
+ teardown?.unsubscribe();
45
+ }
46
+ }
47
+ class ObservableImpl {
48
+ '@@observable' = () => this;
49
+ subscribeFn;
50
+ constructor(subscribeFn) {
51
+ this.subscribeFn = subscribeFn;
52
+ Object.defineProperty(this, getObservableSymbol(), {
53
+ configurable: true,
54
+ value: () => this,
55
+ });
56
+ }
57
+ subscribe(observerOrNext, error, complete) {
58
+ const observer = normalizeObserver(observerOrNext, error, complete);
59
+ let closed = false;
60
+ let teardown;
61
+ let teardownReady = false;
62
+ const subscription = {
63
+ get closed() {
64
+ return closed;
65
+ },
66
+ unsubscribe() {
67
+ if (closed) {
68
+ return;
69
+ }
70
+ closed = true;
71
+ if (teardownReady) {
72
+ runTeardown(teardown);
73
+ }
74
+ },
75
+ };
76
+ const safeObserver = {
77
+ next(value) {
78
+ if (!closed) {
79
+ callObserver(() => observer.next?.(value));
80
+ }
81
+ },
82
+ error(error) {
83
+ if (closed) {
84
+ return;
85
+ }
86
+ closed = true;
87
+ if (observer.error) {
88
+ callObserver(() => observer.error?.(error));
89
+ }
90
+ else {
91
+ reportObserverError(error);
92
+ }
93
+ if (teardownReady) {
94
+ runTeardown(teardown);
95
+ }
96
+ },
97
+ complete() {
98
+ if (closed) {
99
+ return;
100
+ }
101
+ closed = true;
102
+ callObserver(() => observer.complete?.());
103
+ if (teardownReady) {
104
+ runTeardown(teardown);
105
+ }
106
+ },
107
+ };
108
+ try {
109
+ teardown = this.subscribeFn(safeObserver);
110
+ teardownReady = true;
111
+ if (subscription.closed) {
112
+ runTeardown(teardown);
113
+ }
114
+ }
115
+ catch (error) {
116
+ safeObserver.error?.(error);
117
+ }
118
+ return subscription;
119
+ }
120
+ [Symbol.asyncIterator]() {
121
+ return observableToAsyncIterable(this)[Symbol.asyncIterator]();
122
+ }
123
+ }
124
+ export const EMPTY = new ObservableImpl((observer) => {
125
+ observer.complete?.();
126
+ return createClosedSubscription();
127
+ });
128
+ export function createObservableController() {
129
+ const observers = new Set();
130
+ let completed = false;
131
+ let errored = false;
132
+ let thrownError;
133
+ const observable = new ObservableImpl((observer) => {
134
+ if (errored) {
135
+ observer.error?.(thrownError);
136
+ return createClosedSubscription();
137
+ }
138
+ if (completed) {
139
+ observer.complete?.();
140
+ return createClosedSubscription();
141
+ }
142
+ const entry = {
143
+ observer,
144
+ subscription: {
145
+ closed: false,
146
+ unsubscribe() {
147
+ entry.subscription.closed = true;
148
+ observers.delete(entry);
149
+ },
150
+ },
151
+ };
152
+ observers.add(entry);
153
+ return entry.subscription;
154
+ });
155
+ return {
156
+ observable,
157
+ next(value) {
158
+ if (completed || errored) {
159
+ return;
160
+ }
161
+ for (const { observer, subscription } of observers) {
162
+ if (!subscription.closed) {
163
+ callObserver(() => observer.next?.(value));
164
+ }
165
+ }
166
+ },
167
+ error(error) {
168
+ if (completed || errored) {
169
+ return;
170
+ }
171
+ errored = true;
172
+ thrownError = error;
173
+ for (const { observer, subscription } of observers) {
174
+ subscription.closed = true;
175
+ callObserver(() => observer.error?.(error));
176
+ }
177
+ observers.clear();
178
+ },
179
+ complete() {
180
+ if (completed || errored) {
181
+ return;
182
+ }
183
+ completed = true;
184
+ for (const { observer, subscription } of observers) {
185
+ subscription.closed = true;
186
+ callObserver(() => observer.complete?.());
187
+ }
188
+ observers.clear();
189
+ },
190
+ };
191
+ }
192
+ export function isObservableLike(value) {
193
+ return ((typeof value === 'object' || typeof value === 'function') &&
194
+ value != null &&
195
+ 'subscribe' in value &&
196
+ typeof value.subscribe === 'function');
197
+ }
198
+ export function observableToAsyncIterable(source) {
199
+ return {
200
+ [Symbol.asyncIterator]() {
201
+ const values = [];
202
+ const pending = [];
203
+ let completed = false;
204
+ let errored = false;
205
+ let thrownError;
206
+ let subscription;
207
+ const resolvePending = (result) => {
208
+ while (pending.length > 0) {
209
+ pending.shift()?.resolve(result);
210
+ }
211
+ };
212
+ const rejectPending = (error) => {
213
+ while (pending.length > 0) {
214
+ pending.shift()?.reject(error);
215
+ }
216
+ };
217
+ const iterator = {
218
+ next() {
219
+ const item = values.shift();
220
+ if (item) {
221
+ return Promise.resolve({ done: false, value: item.value });
222
+ }
223
+ if (errored) {
224
+ return Promise.reject(thrownError ?? new Error('Observable source failed'));
225
+ }
226
+ if (completed) {
227
+ return Promise.resolve({ done: true, value: undefined });
228
+ }
229
+ return new Promise((resolve, reject) => {
230
+ pending.push({ resolve, reject });
231
+ });
232
+ },
233
+ return() {
234
+ completed = true;
235
+ values.length = 0;
236
+ subscription?.unsubscribe();
237
+ resolvePending({ done: true, value: undefined });
238
+ return Promise.resolve({ done: true, value: undefined });
239
+ },
240
+ };
241
+ try {
242
+ subscription = source.subscribe({
243
+ next(value) {
244
+ if (completed || errored) {
245
+ return;
246
+ }
247
+ const pendingIterator = pending.shift();
248
+ if (pendingIterator) {
249
+ pendingIterator.resolve({ done: false, value });
250
+ return;
251
+ }
252
+ values.push({ value });
253
+ },
254
+ error(error) {
255
+ if (completed || errored) {
256
+ return;
257
+ }
258
+ values.length = 0;
259
+ errored = true;
260
+ thrownError = toError(error);
261
+ rejectPending(thrownError);
262
+ subscription?.unsubscribe();
263
+ },
264
+ complete() {
265
+ if (completed || errored) {
266
+ return;
267
+ }
268
+ completed = true;
269
+ resolvePending({ done: true, value: undefined });
270
+ },
271
+ });
272
+ }
273
+ catch (error) {
274
+ values.length = 0;
275
+ errored = true;
276
+ thrownError = toError(error);
277
+ rejectPending(thrownError);
278
+ }
279
+ return iterator;
280
+ },
281
+ };
282
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depup/inquirer",
3
- "version": "13.4.0-depup.0",
3
+ "version": "14.0.2-depup.23",
4
4
  "description": "A collection of common interactive command line user interfaces. (with updated dependencies)",
5
5
  "keywords": [
6
6
  "inquirer",
@@ -71,16 +71,16 @@
71
71
  "tsc": "tsc"
72
72
  },
73
73
  "dependencies": {
74
- "@inquirer/ansi": "^2.0.5",
75
- "@inquirer/core": "^11.1.8",
76
- "@inquirer/prompts": "^8.4.0",
77
- "@inquirer/type": "^4.0.5",
78
- "mute-stream": "^3.0.0",
79
- "run-async": "^4.0.6",
80
- "rxjs": "^7.8.2"
74
+ "@inquirer/ansi": "^2.0.7",
75
+ "@inquirer/core": "^11.2.1",
76
+ "@inquirer/prompts": "^8.5.2",
77
+ "@inquirer/type": "^4.0.7",
78
+ "mute-stream": "^4.0.0",
79
+ "run-async": "^4.0.6"
81
80
  },
82
81
  "devDependencies": {
83
82
  "@types/mute-stream": "^0.0.4",
83
+ "rxjs": "^7.8.2",
84
84
  "typescript": "^6.0.2"
85
85
  },
86
86
  "peerDependencies": {
@@ -92,17 +92,22 @@
92
92
  }
93
93
  },
94
94
  "engines": {
95
- "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
95
+ "node": ">=23.5.0 || ^22.13.0 || ^20.17.0"
96
96
  },
97
97
  "main": "./dist/index.js",
98
98
  "types": "./dist/index.d.ts",
99
- "gitHead": "e68fe01d65359e083581c48c4a18cd8f97d88842",
99
+ "gitHead": "bfd8710229e3d3c9784bef3bbfbd84c7bd09bb9e",
100
100
  "depup": {
101
- "changes": {},
102
- "depsUpdated": 0,
101
+ "changes": {
102
+ "mute-stream": {
103
+ "from": "^3.0.0",
104
+ "to": "^4.0.0"
105
+ }
106
+ },
107
+ "depsUpdated": 1,
103
108
  "originalPackage": "inquirer",
104
- "originalVersion": "13.4.0",
105
- "processedAt": "2026-04-06T20:24:22.833Z",
109
+ "originalVersion": "14.0.2",
110
+ "processedAt": "2026-07-21T17:16:45.498Z",
106
111
  "smokeTest": "passed"
107
112
  }
108
113
  }