Skip to content

Commit 134a1a1

Browse files
authored
fix(prompts): respect directory option in path prompt (#483)
1 parent 9786226 commit 134a1a1

4 files changed

Lines changed: 102 additions & 21 deletions

File tree

.changeset/big-pants-invite.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clack/prompts": patch
3+
---
4+
5+
Fix the `path` prompt so `directory: true` correctly enforces directory-only selection while still allowing directory navigation, and add regression tests for both directory and default file selection behavior.

packages/prompts/src/path.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export const path = (opts: PathOptions) => {
6363
})
6464
.filter(
6565
({ path, isDirectory }) =>
66-
path.startsWith(userInput) && (opts.directory || !isDirectory)
66+
path.startsWith(userInput) && (isDirectory || !opts.directory)
6767
);
6868
return items.map((item) => ({
6969
value: item.path,

packages/prompts/test/__snapshots__/path.test.ts.snap

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ exports[`text (isCI = false) > can cancel 1`] = `
88
│
99
│ Search: /tmp/█
1010
│ ● /tmp/bar
11+
│ ○ /tmp/foo
12+
│ ○ /tmp/hello
1113
│ ○ /tmp/root.zip
1214
│ ↑/↓ to select • Enter: confirm • Type: to search
1315
└",
14-
"<cursor.backward count=999><cursor.up count=7>",
16+
"<cursor.backward count=999><cursor.up count=9>",
1517
"<cursor.down count=1>",
1618
"<erase.down>",
1719
"■ foo
@@ -30,10 +32,12 @@ exports[`text (isCI = false) > cannot submit unknown value 1`] = `
3032
│
3133
│ Search: /tmp/█
3234
│ ● /tmp/bar
35+
│ ○ /tmp/foo
36+
│ ○ /tmp/hello
3337
│ ○ /tmp/root.zip
3438
│ ↑/↓ to select • Enter: confirm • Type: to search
3539
└",
36-
"<cursor.backward count=999><cursor.up count=7>",
40+
"<cursor.backward count=999><cursor.up count=9>",
3741
"<cursor.down count=3>",
3842
"<erase.down>",
3943
"│ Search: /tmp/_█
@@ -57,10 +61,12 @@ exports[`text (isCI = false) > cannot submit unknown value 1`] = `
5761
│
5862
│ Search: /tmp/█
5963
│ ● /tmp/bar
64+
│ ○ /tmp/foo
65+
│ ○ /tmp/hello
6066
│ ○ /tmp/root.zip
6167
│ ↑/↓ to select • Enter: confirm • Type: to search
6268
└",
63-
"<cursor.backward count=999><cursor.up count=7>",
69+
"<cursor.backward count=999><cursor.up count=9>",
6470
"<cursor.down count=3>",
6571
"<erase.down>",
6672
"│ Search: /tmp/b█
@@ -107,10 +113,12 @@ exports[`text (isCI = false) > renders cancelled value if one set 1`] = `
107113
│
108114
│ Search: /tmp/█
109115
│ ● /tmp/bar
116+
│ ○ /tmp/foo
117+
│ ○ /tmp/hello
110118
│ ○ /tmp/root.zip
111119
│ ↑/↓ to select • Enter: confirm • Type: to search
112120
└",
113-
"<cursor.backward count=999><cursor.up count=7>",
121+
"<cursor.backward count=999><cursor.up count=9>",
114122
"<cursor.down count=3>",
115123
"<erase.down>",
116124
"│ Search: /tmp/x█
@@ -141,10 +149,12 @@ exports[`text (isCI = false) > renders message 1`] = `
141149
│
142150
│ Search: /tmp/█
143151
│ ● /tmp/bar
152+
│ ○ /tmp/foo
153+
│ ○ /tmp/hello
144154
│ ○ /tmp/root.zip
145155
│ ↑/↓ to select • Enter: confirm • Type: to search
146156
└",
147-
"<cursor.backward count=999><cursor.up count=7>",
157+
"<cursor.backward count=999><cursor.up count=9>",
148158
"<cursor.down count=1>",
149159
"<erase.down>",
150160
"◇ foo
@@ -163,10 +173,12 @@ exports[`text (isCI = false) > renders submitted value 1`] = `
163173
│
164174
│ Search: /tmp/█
165175
│ ● /tmp/bar
176+
│ ○ /tmp/foo
177+
│ ○ /tmp/hello
166178
│ ○ /tmp/root.zip
167179
│ ↑/↓ to select • Enter: confirm • Type: to search
168180
└",
169-
"<cursor.backward count=999><cursor.up count=7>",
181+
"<cursor.backward count=999><cursor.up count=9>",
170182
"<cursor.down count=3>",
171183
"<erase.down>",
172184
"│ Search: /tmp/b█
@@ -197,10 +209,12 @@ exports[`text (isCI = false) > validation errors render and clear (using Error)
197209
│
198210
│ Search: /tmp/█
199211
│ ● /tmp/bar
212+
│ ○ /tmp/foo
213+
│ ○ /tmp/hello
200214
│ ○ /tmp/root.zip
201215
│ ↑/↓ to select • Enter: confirm • Type: to search
202216
└",
203-
"<cursor.backward count=999><cursor.up count=7>",
217+
"<cursor.backward count=999><cursor.up count=9>",
204218
"<cursor.down count=3>",
205219
"<erase.down>",
206220
"│ Search: /tmp/r█
@@ -224,10 +238,12 @@ exports[`text (isCI = false) > validation errors render and clear (using Error)
224238
│
225239
│ Search: /tmp/█
226240
│ ○ /tmp/bar
241+
│ ○ /tmp/foo
242+
│ ○ /tmp/hello
227243
│ ● /tmp/root.zip
228244
│ ↑/↓ to select • Enter: confirm • Type: to search
229245
└",
230-
"<cursor.backward count=999><cursor.up count=7>",
246+
"<cursor.backward count=999><cursor.up count=9>",
231247
"<cursor.down count=3>",
232248
"<erase.down>",
233249
"│ Search: /tmp/b█
@@ -253,10 +269,12 @@ exports[`text (isCI = false) > validation errors render and clear 1`] = `
253269
│
254270
│ Search: /tmp/█
255271
│ ● /tmp/bar
272+
│ ○ /tmp/foo
273+
│ ○ /tmp/hello
256274
│ ○ /tmp/root.zip
257275
│ ↑/↓ to select • Enter: confirm • Type: to search
258276
└",
259-
"<cursor.backward count=999><cursor.up count=7>",
277+
"<cursor.backward count=999><cursor.up count=9>",
260278
"<cursor.down count=3>",
261279
"<erase.down>",
262280
"│ Search: /tmp/r█
@@ -280,10 +298,12 @@ exports[`text (isCI = false) > validation errors render and clear 1`] = `
280298
│
281299
│ Search: /tmp/█
282300
│ ○ /tmp/bar
301+
│ ○ /tmp/foo
302+
│ ○ /tmp/hello
283303
│ ● /tmp/root.zip
284304
│ ↑/↓ to select • Enter: confirm • Type: to search
285305
└",
286-
"<cursor.backward count=999><cursor.up count=7>",
306+
"<cursor.backward count=999><cursor.up count=9>",
287307
"<cursor.down count=3>",
288308
"<erase.down>",
289309
"│ Search: /tmp/b█
@@ -309,10 +329,12 @@ exports[`text (isCI = true) > can cancel 1`] = `
309329
│
310330
│ Search: /tmp/█
311331
│ ● /tmp/bar
332+
│ ○ /tmp/foo
333+
│ ○ /tmp/hello
312334
│ ○ /tmp/root.zip
313335
│ ↑/↓ to select • Enter: confirm • Type: to search
314336
└",
315-
"<cursor.backward count=999><cursor.up count=7>",
337+
"<cursor.backward count=999><cursor.up count=9>",
316338
"<cursor.down count=1>",
317339
"<erase.down>",
318340
"■ foo
@@ -331,10 +353,12 @@ exports[`text (isCI = true) > cannot submit unknown value 1`] = `
331353
│
332354
│ Search: /tmp/█
333355
│ ● /tmp/bar
356+
│ ○ /tmp/foo
357+
│ ○ /tmp/hello
334358
│ ○ /tmp/root.zip
335359
│ ↑/↓ to select • Enter: confirm • Type: to search
336360
└",
337-
"<cursor.backward count=999><cursor.up count=7>",
361+
"<cursor.backward count=999><cursor.up count=9>",
338362
"<cursor.down count=3>",
339363
"<erase.down>",
340364
"│ Search: /tmp/_█
@@ -358,10 +382,12 @@ exports[`text (isCI = true) > cannot submit unknown value 1`] = `
358382
│
359383
│ Search: /tmp/█
360384
│ ● /tmp/bar
385+
│ ○ /tmp/foo
386+
│ ○ /tmp/hello
361387
│ ○ /tmp/root.zip
362388
│ ↑/↓ to select • Enter: confirm • Type: to search
363389
└",
364-
"<cursor.backward count=999><cursor.up count=7>",
390+
"<cursor.backward count=999><cursor.up count=9>",
365391
"<cursor.down count=3>",
366392
"<erase.down>",
367393
"│ Search: /tmp/b█
@@ -408,10 +434,12 @@ exports[`text (isCI = true) > renders cancelled value if one set 1`] = `
408434
│
409435
│ Search: /tmp/█
410436
│ ● /tmp/bar
437+
│ ○ /tmp/foo
438+
│ ○ /tmp/hello
411439
│ ○ /tmp/root.zip
412440
│ ↑/↓ to select • Enter: confirm • Type: to search
413441
└",
414-
"<cursor.backward count=999><cursor.up count=7>",
442+
"<cursor.backward count=999><cursor.up count=9>",
415443
"<cursor.down count=3>",
416444
"<erase.down>",
417445
"│ Search: /tmp/x█
@@ -442,10 +470,12 @@ exports[`text (isCI = true) > renders message 1`] = `
442470
│
443471
│ Search: /tmp/█
444472
│ ● /tmp/bar
473+
│ ○ /tmp/foo
474+
│ ○ /tmp/hello
445475
│ ○ /tmp/root.zip
446476
│ ↑/↓ to select • Enter: confirm • Type: to search
447477
└",
448-
"<cursor.backward count=999><cursor.up count=7>",
478+
"<cursor.backward count=999><cursor.up count=9>",
449479
"<cursor.down count=1>",
450480
"<erase.down>",
451481
"◇ foo
@@ -464,10 +494,12 @@ exports[`text (isCI = true) > renders submitted value 1`] = `
464494
│
465495
│ Search: /tmp/█
466496
│ ● /tmp/bar
497+
│ ○ /tmp/foo
498+
│ ○ /tmp/hello
467499
│ ○ /tmp/root.zip
468500
│ ↑/↓ to select • Enter: confirm • Type: to search
469501
└",
470-
"<cursor.backward count=999><cursor.up count=7>",
502+
"<cursor.backward count=999><cursor.up count=9>",
471503
"<cursor.down count=3>",
472504
"<erase.down>",
473505
"│ Search: /tmp/b█
@@ -498,10 +530,12 @@ exports[`text (isCI = true) > validation errors render and clear (using Error) 1
498530
│
499531
│ Search: /tmp/█
500532
│ ● /tmp/bar
533+
│ ○ /tmp/foo
534+
│ ○ /tmp/hello
501535
│ ○ /tmp/root.zip
502536
│ ↑/↓ to select • Enter: confirm • Type: to search
503537
└",
504-
"<cursor.backward count=999><cursor.up count=7>",
538+
"<cursor.backward count=999><cursor.up count=9>",
505539
"<cursor.down count=3>",
506540
"<erase.down>",
507541
"│ Search: /tmp/r█
@@ -525,10 +559,12 @@ exports[`text (isCI = true) > validation errors render and clear (using Error) 1
525559
│
526560
│ Search: /tmp/█
527561
│ ○ /tmp/bar
562+
│ ○ /tmp/foo
563+
│ ○ /tmp/hello
528564
│ ● /tmp/root.zip
529565
│ ↑/↓ to select • Enter: confirm • Type: to search
530566
└",
531-
"<cursor.backward count=999><cursor.up count=7>",
567+
"<cursor.backward count=999><cursor.up count=9>",
532568
"<cursor.down count=3>",
533569
"<erase.down>",
534570
"│ Search: /tmp/b█
@@ -554,10 +590,12 @@ exports[`text (isCI = true) > validation errors render and clear 1`] = `
554590
│
555591
│ Search: /tmp/█
556592
│ ● /tmp/bar
593+
│ ○ /tmp/foo
594+
│ ○ /tmp/hello
557595
│ ○ /tmp/root.zip
558596
│ ↑/↓ to select • Enter: confirm • Type: to search
559597
└",
560-
"<cursor.backward count=999><cursor.up count=7>",
598+
"<cursor.backward count=999><cursor.up count=9>",
561599
"<cursor.down count=3>",
562600
"<erase.down>",
563601
"│ Search: /tmp/r█
@@ -581,10 +619,12 @@ exports[`text (isCI = true) > validation errors render and clear 1`] = `
581619
│
582620
│ Search: /tmp/█
583621
│ ○ /tmp/bar
622+
│ ○ /tmp/foo
623+
│ ○ /tmp/hello
584624
│ ● /tmp/root.zip
585625
│ ↑/↓ to select • Enter: confirm • Type: to search
586626
└",
587-
"<cursor.backward count=999><cursor.up count=7>",
627+
"<cursor.backward count=999><cursor.up count=9>",
588628
"<cursor.down count=3>",
589629
"<erase.down>",
590630
"│ Search: /tmp/b█

packages/prompts/test/path.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,42 @@ describe.each(['true', 'false'])('text (isCI = %s)', (isCI) => {
146146
expect(output.buffer).toMatchSnapshot();
147147
});
148148

149+
test('directory mode only allows selecting directories', async () => {
150+
const result = prompts.path({
151+
message: 'foo',
152+
root: '/tmp/',
153+
directory: true,
154+
input,
155+
output,
156+
});
157+
158+
input.emit('keypress', 'f', { name: 'f' });
159+
input.emit('keypress', '', { name: 'return' });
160+
161+
const value = await result;
162+
163+
expect(value).toBe('/tmp/foo');
164+
});
165+
166+
test('default mode allows selecting files', async () => {
167+
const result = prompts.path({
168+
message: 'foo',
169+
root: '/tmp/',
170+
input,
171+
output,
172+
});
173+
174+
input.emit('keypress', 'r', { name: 'r' });
175+
input.emit('keypress', 'o', { name: 'o' });
176+
input.emit('keypress', 'o', { name: 'o' });
177+
input.emit('keypress', 't', { name: 't' });
178+
input.emit('keypress', '', { name: 'return' });
179+
180+
const value = await result;
181+
182+
expect(value).toBe('/tmp/root.zip');
183+
});
184+
149185
test('validation errors render and clear', async () => {
150186
const result = prompts.path({
151187
message: 'foo',

0 commit comments

Comments
 (0)