refactor(cli): extract template props prompting to own module

This commit is contained in:
Julien Oculi 2024-04-03 17:38:51 +02:00
parent 7022ebc866
commit 7fb5167308
2 changed files with 50 additions and 36 deletions

48
cli/_prompt_template.ts Normal file
View file

@ -0,0 +1,48 @@
import { Input } from '@cliffy/prompt/input.ts'
import type { Template } from '../types.ts'
import type { JSX } from 'preact'
const decoder = new TextDecoder()
export async function promptProps<
Builder extends (props: Props) => JSX.Element,
Props extends Record<string, unknown>,
>(template: Template<Builder, Props>): Promise<Props> {
const props: Partial<Props> = {}
for (const prop of template.props) {
if (prop.multiline) {
console.log(
`%c?%c ${prop.description} %c[end input with "!EOF" on a new line] %c`,
'color: yellow;',
'font-weight: bold',
'color: white',
'color: blue',
)
for await (const chunk of Deno.stdin.readable) {
const text = decoder.decode(chunk)
if (text.startsWith('!EOF\n')) {
break
}
//@ts-ignore TODO fix type inference
props[prop.tag] += text
}
//@ts-ignore TODO fix type inference
if (props[prop.tag].startsWith('undefined')) {
//@ts-ignore TODO fix type inference
props[prop.tag] = props[prop.tag].slice('undefined'.length)
}
} else {
const value = await Input.prompt({
message: prop.description,
})
//@ts-ignore TODO fix type inference
props[prop.tag] = value
}
}
return props as Props
}

View file

@ -1,9 +1,9 @@
import { Command } from '@cliffy/command/mod.ts'
import { Input } from '@cliffy/prompt/mod.ts'
import { Contact } from '../src/contact.ts'
import { send } from '../src/send.ts'
import type { Mail } from '../types.ts'
import { templates, templateType } from './_templates_loader.ts'
import { promptProps } from './_prompt_template.ts'
//TODO completions for "--from"
//TODO require sudo for "--from !== !me"
@ -54,41 +54,7 @@ export const cmd = new Command()
})()
const selectedTemplate = templates.get(template)!
type Props = typeof selectedTemplate
const props: Partial<Props> = {}
for (const prop of selectedTemplate.props) {
if (prop.multiline) {
console.log(
`%c?%c ${prop.description} %c[end input with "!EOF" on a new line] %c`,
'color: yellow;',
'font-weight: bold',
'color: white',
'color: blue',
)
const decoder = new TextDecoder()
for await (const chunk of Deno.stdin.readable) {
const text = decoder.decode(chunk)
if (text.startsWith('!EOF\n')) {
break
}
//@ts-ignore TODO fix type inference
props[prop.tag] += text
}
//@ts-ignore TODO fix type inference
if (props[prop.tag].startsWith('undefined')) {
//@ts-ignore TODO fix type inference
props[prop.tag] = props[prop.tag].slice('undefined'.length)
}
} else {
const value = await Input.prompt({
message: prop.description,
})
//@ts-ignore TODO fix type inference
props[prop.tag] = value
}
}
const props = await promptProps(selectedTemplate)
const mail: Mail = {
from: fromContact,