diff --git a/src/components.tsx b/src/components.tsx
deleted file mode 100644
index 514186f..0000000
--- a/src/components.tsx
+++ /dev/null
@@ -1,209 +0,0 @@
-import React from "react";
-import ReactDOMServer from "react-dom/server";
-import { Builder } from "xml2js";
-import cryptoRandomString from "crypto-random-string";
-
-export type Inbox = {
- name: string;
- token: string;
-};
-
-export function Layout({ children }: { children: React.ReactNode }) {
- return (
-
-
-
-
-
-
-
-
-
-
- Kill the Newsletter!
-
-
-
- {children}
-
-
-
- );
-}
-
-export function Form() {
- return (
-
- );
-}
-
-export function Created({ inbox: { name, token } }: { inbox: Inbox }) {
- return (
- <>
- “{name}” Inbox Created
-
- Sign up for the newsletter with
-
- {feedEmail(token)}
-
-
- Subscribe to the Atom feed at
-
- {feedUrl(token)}
-
-
- Don’t share these addresses.
-
- They contain a security token that other people could use
-
- to send you spam and to control your newsletter subscriptions.
-
- Enjoy your readings!
-
-
- Create Another Inbox
-
-
- >
- );
-}
-
-// https://validator.w3.org/feed/docs/atom.html
-// https://validator.w3.org/feed/#validate_by_input
-
-export function Feed(inbox: Inbox) {
- const { name, token } = inbox;
- return {
- feed: {
- $: { xmlns: "http://www.w3.org/2005/Atom" },
- link: [
- {
- $: {
- rel: "self",
- type: "application/atom+xml",
- href: feedUrl(token)
- }
- },
- {
- $: {
- rel: "alternate",
- type: "text/html",
- href: "https://www.kill-the-newsletter.com/"
- }
- }
- ],
- id: id(token),
- title: name,
- subtitle: `Kill the Newsletter! Inbox “${feedEmail(token)}”`,
- updated: now(),
- ...Entry({
- title: `“${name}” Inbox Created`,
- author: "Kill the Newsletter!",
- content: ReactDOMServer.renderToStaticMarkup(
-
- )
- })
- }
- };
-}
-
-export function Entry({
- title,
- author,
- content
-}: {
- title: string;
- author: string;
- content: string;
-}) {
- return {
- entry: {
- id: id(newToken()),
- title,
- author: { name: author },
- updated: now(),
- content: { $: { type: "html" }, _: content }
- }
- };
-}
-
-export function newToken() {
- return cryptoRandomString({
- length: 20,
- characters: "1234567890qwertyuiopasdfghjklzxcvbnm"
- });
-}
-
-export function now() {
- return new Date().toISOString();
-}
-
-export function feedPath(token: string) {
- return `static/feeds/${token}.xml`;
-}
-
-export function feedUrl(token: string) {
- return `https://www.kill-the-newsletter.com/feeds/${token}.xml`;
-}
-
-export function feedEmail(token: string) {
- return `${token}@kill-the-newsletter.com`;
-}
-
-export function id(token: string) {
- return `urn:kill-the-newsletter:${token}`;
-}
-
-export function renderHtml(component: React.ReactElement): string {
- return `\n${ReactDOMServer.renderToStaticMarkup(component)}`;
-}
-
-export function renderXml(xml: object): string {
- return new Builder().buildObject(xml);
-}
diff --git a/src/server.tsx b/src/server.tsx
index 4c514e6..4777ef9 100644
--- a/src/server.tsx
+++ b/src/server.tsx
@@ -1,17 +1,9 @@
import express from "express";
import React from "react";
-import {
- Inbox,
- Layout,
- Form,
- Created,
- Feed,
- newToken,
- feedPath,
- renderHtml,
- renderXml
-} from "./components";
import fs from "fs";
+import ReactDOMServer from "react-dom/server";
+import { Builder } from "xml2js";
+import cryptoRandomString from "crypto-random-string";
export const webServer = express()
.use(express.static("static"))
@@ -37,3 +29,208 @@ export const webServer = express()
);
})
.listen(8443);
+
+type Inbox = {
+ name: string;
+ token: string;
+};
+
+function Layout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+
+
+
+
+
+
+
+
+ Kill the Newsletter!
+
+
+
+ {children}
+
+
+
+ );
+}
+
+function Form() {
+ return (
+
+ );
+}
+
+function Created({ inbox: { name, token } }: { inbox: Inbox }) {
+ return (
+ <>
+ “{name}” Inbox Created
+
+ Sign up for the newsletter with
+
+ {feedEmail(token)}
+
+
+ Subscribe to the Atom feed at
+
+ {feedUrl(token)}
+
+
+ Don’t share these addresses.
+
+ They contain a security token that other people could use
+
+ to send you spam and to control your newsletter subscriptions.
+
+ Enjoy your readings!
+
+
+ Create Another Inbox
+
+
+ >
+ );
+}
+
+// https://validator.w3.org/feed/docs/atom.html
+// https://validator.w3.org/feed/#validate_by_input
+
+function Feed(inbox: Inbox) {
+ const { name, token } = inbox;
+ return {
+ feed: {
+ $: { xmlns: "http://www.w3.org/2005/Atom" },
+ link: [
+ {
+ $: {
+ rel: "self",
+ type: "application/atom+xml",
+ href: feedUrl(token)
+ }
+ },
+ {
+ $: {
+ rel: "alternate",
+ type: "text/html",
+ href: "https://www.kill-the-newsletter.com/"
+ }
+ }
+ ],
+ id: id(token),
+ title: name,
+ subtitle: `Kill the Newsletter! Inbox “${feedEmail(token)}”`,
+ updated: now(),
+ ...Entry({
+ title: `“${name}” Inbox Created`,
+ author: "Kill the Newsletter!",
+ content: ReactDOMServer.renderToStaticMarkup(
+
+ )
+ })
+ }
+ };
+}
+
+function Entry({
+ title,
+ author,
+ content
+}: {
+ title: string;
+ author: string;
+ content: string;
+}) {
+ return {
+ entry: {
+ id: id(newToken()),
+ title,
+ author: { name: author },
+ updated: now(),
+ content: { $: { type: "html" }, _: content }
+ }
+ };
+}
+
+function newToken() {
+ return cryptoRandomString({
+ length: 20,
+ characters: "1234567890qwertyuiopasdfghjklzxcvbnm"
+ });
+}
+
+function now() {
+ return new Date().toISOString();
+}
+
+export function feedPath(token: string) {
+ return `static/feeds/${token}.xml`;
+}
+
+function feedUrl(token: string) {
+ return `https://www.kill-the-newsletter.com/feeds/${token}.xml`;
+}
+
+function feedEmail(token: string) {
+ return `${token}@kill-the-newsletter.com`;
+}
+
+function id(token: string) {
+ return `urn:kill-the-newsletter:${token}`;
+}
+
+function renderHtml(component: React.ReactElement): string {
+ return `\n${ReactDOMServer.renderToStaticMarkup(component)}`;
+}
+
+function renderXml(xml: object): string {
+ return new Builder().buildObject(xml);
+}
diff --git a/src/test.ts b/src/test.ts
index aa7c7ce..07557de 100644
--- a/src/test.ts
+++ b/src/test.ts
@@ -1,5 +1,4 @@
-import { webServer } from "./server";
-import { feedPath } from "./components";
+import { webServer, feedPath } from "./server";
import fetch from "node-fetch";
import fs from "fs";