Compare commits

...

7 commits

10 changed files with 57 additions and 10 deletions

View file

@ -8,6 +8,20 @@ Mail cli for Coh@bit.
## Installation
### From [jsr](https://jsr.io)
```sh
deno install \
--allow-read \
--allow-env \
--allow-net=0.0.0.0 \
--allow-sys=osRelease,networkInterfaces \
--allow-run=/usr/sbin/sendmail,whoami \
--global --force --name=cohamail jsr:@cohabit/mailer/cli
```
### From sources
> [!WARNING]
>
> Currently bin manually added to [releases](./releases) tab. Prefer `git clone`

20
cli.ts
View file

@ -1,14 +1,34 @@
import config from './deno.json' with { type: 'json' }
import { Command } from '@cliffy/command'
import { UpgradeCommand } from '@cliffy/command/upgrade'
import { JsrProvider } from '@cliffy/command/upgrade/provider/jsr'
import { cmd as send } from './cli/send.ts'
import { cmd as preview } from './cli/preview.ts'
const upgradeCommand = new UpgradeCommand({
args: [
'--allow-read',
'--allow-env',
'--allow-net=0.0.0.0',
'--allow-sys=osRelease,networkInterfaces',
'--allow-run=/usr/sbin/sendmail,whoami',
'--name=cohamail',
],
provider: [
new JsrProvider({
package: config.name as `@${string}/${string}`,
main: 'cli',
}),
],
})
const cli = new Command()
.name('cohamail')
.description('Mail cli for coh@bit.')
.version(config.version)
.command('preview', preview)
.command('send', send)
.command('upgrade', upgradeCommand)
if (import.meta.main) {
if (Deno.args.length) {

View file

@ -1,6 +1,6 @@
{
"name": "@cohabit/mailer",
"version": "0.2.1",
"version": "0.3.0",
"exports": {
".": "./mod.ts",
"./cli": "./cli.ts",

View file

@ -14,6 +14,7 @@
"jsr:@std/cli@1.0.0-rc.2": "jsr:@std/cli@1.0.0-rc.2",
"jsr:@std/encoding@1.0.0-rc.2": "jsr:@std/encoding@1.0.0-rc.2",
"jsr:@std/fmt@~0.225.4": "jsr:@std/fmt@0.225.6",
"jsr:@std/io@~0.224.2": "jsr:@std/io@0.224.3",
"jsr:@std/path@1.0.0-rc.2": "jsr:@std/path@1.0.0-rc.2",
"jsr:@std/path@^0.221.0": "jsr:@std/path@0.221.0",
"jsr:@std/text@1.0.0-rc.1": "jsr:@std/text@1.0.0-rc.1",
@ -59,6 +60,7 @@
"jsr:@cliffy/keycode@1.0.0-rc.5",
"jsr:@std/assert@1.0.0-rc.2",
"jsr:@std/fmt@~0.225.4",
"jsr:@std/io@~0.224.2",
"jsr:@std/path@1.0.0-rc.2",
"jsr:@std/text@1.0.0-rc.1"
]
@ -84,6 +86,9 @@
"@std/fmt@0.225.6": {
"integrity": "aba6aea27f66813cecfd9484e074a9e9845782ab0685c030e453a8a70b37afc8"
},
"@std/io@0.224.3": {
"integrity": "b402edeb99c6b3778d9ae3e9927bc9085b170b41e5a09bbb7064ab2ee394ae2f"
},
"@std/path@0.221.0": {
"integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095",
"dependencies": [

View file

@ -1,14 +1,16 @@
import accounts from '../config/account.json' with { type: 'json' }
import dkim from '../config/dkim.json' with { type: 'json' }
export type AddressString = `${string}@${string}.${string}`
export class Contact {
#name: string
#address: `${string}@${string}.${string}`
#address: AddressString
constructor(
{ name, address }: {
name: string
address: `${string}@${string}.${string}`
address: AddressString
},
) {
this.#name = name
@ -60,18 +62,18 @@ export class Contact {
return `${this.#name} <${this.#address}>`
}
toJSON() {
toJSON(): { name: string; address: AddressString } {
return {
name: this.#name,
address: this.#address,
} as const
}
get name() {
get name(): string {
return this.#name
}
get address() {
get address(): AddressString {
return this.#address
}
}

View file

@ -1,8 +1,11 @@
import type SendmailTransport from 'npm:@types/nodemailer'
import type { Mail } from '../types.ts'
import { renderTemplate } from './template.tsx'
import { transporter } from './transporter.ts'
export async function send(mail: Mail) {
export async function send(
mail: Mail,
): Promise<SendmailTransport.SentMessageInfo> {
const { html, text } = await renderTemplate(mail.body)
return (await transporter()).sendMail({

View file

@ -4,6 +4,8 @@ import { render } from 'jsx-email'
import Turndown from 'turndown'
import type { JSX } from 'preact'
console.assert(React !== undefined)
const htmlToMd = new Turndown({
headingStyle: 'atx',
codeBlockStyle: 'fenced',

View file

@ -28,7 +28,7 @@ function MagicLink(
ip?: string
endpoint: string
},
) {
): JSX.Element {
return (
<Html lang='fr' style={{ fontSize: '14px' }}>
<BaseStyle />

View file

@ -2,10 +2,11 @@ import { Body, Container, Html, Markdown, Preview } from 'jsx-email'
import { Signature } from './components/Signature.tsx'
import type { Template } from '../types.ts'
import { BaseStyle, bodyCss, messageCss, textCss } from './styles/base.tsx'
import type { JSX } from 'preact'
function Message(
{ summary, body }: { summary?: string; body: string },
) {
): JSX.Element {
return (
<Html lang='fr' style={{ fontSize: '14px' }}>
<BaseStyle />

View file

@ -29,7 +29,7 @@ function Welcome(
login: string
endpoint?: string
},
) {
): JSX.Element {
return (
<Html lang='fr' style={{ fontSize: '14px' }}>
<BaseStyle />