diff --git a/cli/_prompt_template.ts b/cli/_prompt_template.ts new file mode 100644 index 0000000..23f4b61 --- /dev/null +++ b/cli/_prompt_template.ts @@ -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, +>(template: Template): Promise { + const props: Partial = {} + + 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 +} diff --git a/cli/send.ts b/cli/send.ts index 5e2e6f0..def2e76 100644 --- a/cli/send.ts +++ b/cli/send.ts @@ -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 = {} - 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,