Skip to content

Commit be07596

Browse files
committed
Merge remote-tracking branch 'origin/main' into deps
2 parents c2f0860 + fdeb9e7 commit be07596

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/parse-procedure.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,14 +477,22 @@ const toRoughJsonSchema7 = (schema: JSONSchema7Definition | undefined): JSONSche
477477
return schema
478478
}
479479

480-
const parameterName = (s: JSONSchema7Definition, position: number): string => {
481-
if (looksLikeArray(s)) {
480+
const maybeParameterName = (s: JSONSchema7Definition): string | undefined => {
481+
const value = schemaDefPropValue(s, 'title') || schemaDefPropValue(s, 'description')
482+
// only look at array item title if we don't have one for the outer array itself
483+
// e.g. for {title: 'file collection', items: {title: 'file'}} we prefer 'file collection' as the parameter name
484+
if (!value && looksLikeArray(s)) {
482485
const items = toRoughJsonSchema7(s).items
483-
const elementName = parameterName(!items || Array.isArray(items) ? {} : items, position)
484-
return `[${elementName.slice(1, -1)}...]`
486+
return items && !Array.isArray(items) ? maybeParameterName(items) : undefined
485487
}
488+
return value
489+
}
490+
491+
const parameterName = (s: JSONSchema7Definition, position: number): string => {
492+
let name = maybeParameterName(s) || `parameter_${position}`
493+
if (looksLikeArray(s)) return `[${name}...]`
494+
486495
// commander requiremenets: no special characters in positional parameters; `<name>` for required and `[name]` for optional parameters
487-
let name = schemaDefPropValue(s, 'title') || schemaDefPropValue(s, 'description') || `parameter_${position}`
488496
name = name.replaceAll(/\W+/g, ' ').trim()
489497
return isOptional(s) ? `[${name}]` : `<${name}>`
490498
}

test/parse.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,32 @@ test('non-primitive option union', async () => {
238238
)
239239
})
240240

241+
test('positional array with title', async () => {
242+
const router = t.router({
243+
foo: t.procedure
244+
.input(z.array(z.string()).describe('files')) //
245+
.query(({input}) => JSON.stringify(input)),
246+
bar: t.procedure
247+
.input(z.array(z.string().describe('files'))) //
248+
.query(({input}) => JSON.stringify(input)),
249+
baz: t.procedure
250+
.input(z.array(z.string().describe('one single file')).describe('file collection'))
251+
.query(({input}) => JSON.stringify(input)),
252+
})
253+
254+
const cli = createCli({router})
255+
expect(await output(cli, ['foo', 'abc', 'def'])).toMatchInlineSnapshot(`"["abc","def"]"`)
256+
expect((await output(cli, ['foo', '--help'])).split('\n')[0]).toMatchInlineSnapshot(
257+
`"Usage: program foo [options] <files...>"`,
258+
)
259+
expect((await output(cli, ['bar', '--help'])).split('\n')[0]).toMatchInlineSnapshot(
260+
`"Usage: program bar [options] <files...>"`,
261+
)
262+
expect((await output(cli, ['baz', '--help'])).split('\n')[0]).toMatchInlineSnapshot(
263+
`"Usage: program baz [options] <file collection...>"`,
264+
)
265+
})
266+
241267
const run = async (cli: TrpcCli, argv: string[]) => {
242268
const exit = vi.fn() as any
243269
const log = vi.fn()

0 commit comments

Comments
 (0)