Add html tagged template literal

This commit is contained in:
Leandro Facchinetti 2020-08-10 00:30:12 +01:00
parent f2fee64925
commit 2724333412
3 changed files with 101 additions and 46 deletions

119
index.ts
View File

@ -8,6 +8,7 @@ import { JSDOM } from "jsdom";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import writeFileAtomic from "write-file-atomic"; import writeFileAtomic from "write-file-atomic";
import cryptoRandomString from "crypto-random-string"; import cryptoRandomString from "crypto-random-string";
import html from "tagged-template-noop";
export const WEB_PORT = process.env.WEB_PORT ?? 8000; export const WEB_PORT = process.env.WEB_PORT ?? 8000;
export const EMAIL_PORT = process.env.EMAIL_PORT ?? 2525; export const EMAIL_PORT = process.env.EMAIL_PORT ?? 2525;
@ -36,7 +37,7 @@ export const webServer = express()
) )
); );
res.send( res.send(
layout(` layout(html`
<p><strong>${H(name)} Inbox Created</strong></p> <p><strong>${H(name)} Inbox Created</strong></p>
${renderedCreated} ${renderedCreated}
`) `)
@ -121,42 +122,76 @@ async function addEntryToFeed(
} }
await writeFileAtomic( await writeFileAtomic(
path, path,
`<?xml version="1.0" encoding="utf-8"?>${feed.serialize()}` html`<?xml version="1.0" encoding="utf-8"?>${feed.serialize()}`.trim()
); );
} }
function layout(content: string): string { function layout(content: string): string {
return `<!DOCTYPE html> return html`
<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kill the Newsletter!</title> <title>Kill the Newsletter!</title>
<meta name="author" content="Leandro Facchinetti"> <meta name="author" content="Leandro Facchinetti" />
<meta name="description" content="Convert email newsletters into Atom feeds."> <meta
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> name="description"
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> content="Convert email newsletters into Atom feeds."
<link rel="icon" type="image/x-icon" href="/favicon.ico"> />
<link rel="stylesheet" type="text/css" href="/styles.css"> <link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/styles.css" />
</head> </head>
<body> <body>
<header> <header>
<h1><a href="/">Kill the Newsletter!</a></h1> <h1><a href="/">Kill the Newsletter!</a></h1>
<p>Convert email newsletters into Atom feeds</p> <p>Convert email newsletters into Atom feeds</p>
<p><img src="/logo.svg" alt="Convert email newsletters into Atom feeds"></p> <p>
<img
src="/logo.svg"
alt="Convert email newsletters into Atom feeds"
/>
</p>
</header> </header>
<main>${content}</main> <main>${content}</main>
<footer><p>By <a href="https://leafac.com">Leandro Facchinetti</a> · <a href="https://github.com/leafac/kill-the-newsletter.com">Source</a> · <a href="${ISSUE_REPORT}">Report an Issue</a></p></footer> <footer>
<p>
By <a href="https://leafac.com">Leandro Facchinetti</a> ·
<a href="https://github.com/leafac/kill-the-newsletter.com"
>Source</a
>
· <a href="${ISSUE_REPORT}">Report an Issue</a>
</p>
</footer>
</body> </body>
</html> </html>
`; `.trim();
} }
function newInbox(): string { function newInbox(): string {
return ` return html`
<form method="POST" action="/"> <form method="POST" action="/">
<p> <p>
<input type="text" name="name" placeholder="Newsletter Name…" maxlength="500" size="30" required> <input
type="text"
name="name"
placeholder="Newsletter Name…"
maxlength="500"
size="30"
required
/>
<button>Create Inbox</button> <button>Create Inbox</button>
</p> </p>
</form> </form>
@ -164,33 +199,45 @@ function newInbox(): string {
} }
function created(identifier: string): string { function created(identifier: string): string {
return ` return html`
<p>Sign up for the newsletter with<br><code>${feedEmail( <p>
identifier Sign up for the newsletter with<br /><code>${feedEmail(identifier)}</code>
)}</code></p> </p>
<p>Subscribe to the Atom feed at<br><code>${feedURL(identifier)}</code></p> <p>
<p>Dont share these addresses.<br>They contain an identifier that other people could use<br>to send you spam and to control your newsletter subscriptions.</p> Subscribe to the Atom feed at<br /><code>${feedURL(identifier)}</code>
</p>
<p>
Dont share these addresses.<br />They contain an identifier that other
people could use<br />to send you spam and to control your newsletter
subscriptions.
</p>
<p>Enjoy your readings!</p> <p>Enjoy your readings!</p>
<p><a href="${BASE_URL}"><strong>Create Another Inbox</strong></a></p> <p>
<a href="${BASE_URL}"><strong>Create Another Inbox</strong></a>
</p>
`.trim(); `.trim();
} }
function feed(identifier: string, name: string): string { function feed(identifier: string, name: string): string {
return `<?xml version="1.0" encoding="utf-8"?> return html`
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"> <feed xmlns="http://www.w3.org/2005/Atom">
<link rel="self" type="application/atom+xml" href="${feedURL( <link
identifier rel="self"
)}"/> type="application/atom+xml"
href="${feedURL(identifier)}"
/>
<link rel="alternate" type="text/html" href="${BASE_URL}" /> <link rel="alternate" type="text/html" href="${BASE_URL}" />
<id>${urn(identifier)}</id> <id>${urn(identifier)}</id>
<title>${name}</title> <title>${name}</title>
<subtitle>Kill the Newsletter! Inbox: ${feedEmail( <subtitle
identifier >Kill the Newsletter! Inbox: ${feedEmail(identifier)}
)} ${feedURL(identifier)}</subtitle> ${feedURL(identifier)}</subtitle
>
<updated>${now()}</updated> <updated>${now()}</updated>
<author><name>Kill the Newsletter!</name></author> <author><name>Kill the Newsletter!</name></author>
</feed> </feed>
`; `.trim();
} }
function entry( function entry(
@ -199,15 +246,17 @@ function entry(
author: string, author: string,
content: string content: string
): string { ): string {
return ` return html`
<entry> <entry>
<id>${urn(identifier)}</id> <id>${urn(identifier)}</id>
<title>${title}</title> <title>${title}</title>
<author><name>${author}</name></author> <author><name>${author}</name></author>
<updated>${now()}</updated> <updated>${now()}</updated>
<link rel="alternate" type="text/html" href="${alternateURL( <link
identifier rel="alternate"
)}"/> type="text/html"
href="${alternateURL(identifier)}"
/>
<content type="html">${content}</content> <content type="html">${content}</content>
</entry> </entry>
`.trim(); `.trim();

5
package-lock.json generated
View File

@ -7744,6 +7744,11 @@
"integrity": "sha512-gtqfvz5jUIMqWn0kkdkV4G8uiLmJckQ+z6aKy1uyE0OPU/6tStubahtZDiF0ajSRVJht+Vd4pX5DDwQLhAapww==", "integrity": "sha512-gtqfvz5jUIMqWn0kkdkV4G8uiLmJckQ+z6aKy1uyE0OPU/6tStubahtZDiF0ajSRVJht+Vd4pX5DDwQLhAapww==",
"optional": true "optional": true
}, },
"tagged-template-noop": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tagged-template-noop/-/tagged-template-noop-2.1.1.tgz",
"integrity": "sha512-diZ004cBHKVueqSr5p+/EPZhofCBRW7w7zZL71FcK8x+209BbMw77ICrP9AWXpVjPyyyIqRYYFAM4Wjk2HNWQg=="
},
"tar": { "tar": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",

View File

@ -23,6 +23,7 @@
"pm2": "^4.2.3", "pm2": "^4.2.3",
"sanitize-xml-string": "^1.1.0", "sanitize-xml-string": "^1.1.0",
"smtp-server": "^3.6.0", "smtp-server": "^3.6.0",
"tagged-template-noop": "^2.1.1",
"ts-node": "^8.10.1", "ts-node": "^8.10.1",
"typescript": "^3.8.3", "typescript": "^3.8.3",
"write-file-atomic": "^3.0.3" "write-file-atomic": "^3.0.3"