` with the company name and an optional unsubscribe link |
+| `body({ preheaderHtml?, mainHtml?, footerHtml? })` | `` around an optional preheader, main, and footer |
+| `content({ content? })` | A `` around raw HTML. The email shell does not call it |
+| `document({ headHtml?, mainHtml?, footerHtml? })` | Doctype, ``, head, and body |
Omitted strings render empty. The button is present only when both `ctaLabel` and `ctaUrl` are set. The unsubscribe link is present only when `unsubscribeUrl` is set.
-`bodyText`, `content`, and slot strings may contain inline HTML. Callers own that markup.
+`bodyText`, `content`, and slot strings may contain inline HTML. Callers own that markup. `escapeHtml` is exported for text and attribute positions; the shell does not call it.
+
+Subpath exports: `@llazyemail/template-runtime-display/escape`, `/head`, `/body`, and `/main`.
## Scripts
diff --git a/deepseek/body.ts.ts b/deepseek/body.ts.ts
deleted file mode 100644
index 643f2d3..0000000
--- a/deepseek/body.ts.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export interface BodyProps {
- /** Raw HTML for the top of `` (e.g. hidden preheader). */
- preheaderHtml?: string;
- /** `` fragment. */
- mainHtml?: string;
- /** `` fragment. */
- footerHtml?: string;
-}
-
-export function body({
- preheaderHtml = '',
- mainHtml = '',
- footerHtml = '',
-}: BodyProps = {}): string {
- return `
- ${preheaderHtml}
-${mainHtml}
-${footerHtml}
- `;
-}
diff --git a/deepseek/head.ts.ts b/deepseek/head.ts.ts
deleted file mode 100644
index 22b26fe..0000000
--- a/deepseek/head.ts.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-export interface HeadProps {
- /** Text for ``. Empty when omitted. */
- title?: string;
- /** Inbox preview text. Rendered as a hidden span at the top of ``. */
- preview?: string;
- /** Raw CSS injected into a ``
- : '';
- return `
-
-
-
-
-
- ${title ?? ''}
- ${previewHtml}
- ${stylesHtml}
- ${extraHead ?? ''}
- `;
-}
diff --git a/deepseek/index.ts.ts b/deepseek/index.ts.ts
deleted file mode 100644
index d91e36c..0000000
--- a/deepseek/index.ts.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { escapeHtml } from './escape.ts';
-export { head, type HeadProps } from './head.ts';
-export { body, type BodyProps } from './body.ts';
-export { main, type MainProps } from './main.ts';
diff --git a/deepseek/main.ts.ts b/deepseek/main.ts.ts
deleted file mode 100644
index e5e7f4a..0000000
--- a/deepseek/main.ts.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export interface MainProps {
- /** Raw inner HTML of ``. */
- innerHtml?: string;
-}
-
-export function main({ innerHtml = '' }: MainProps = {}): string {
- return `
-${innerHtml}
- `;
-}
diff --git a/deepseek/package.json b/deepseek/package.json
deleted file mode 100644
index 755bb62..0000000
--- a/deepseek/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "template-runtime-display",
- "version": "0.2.0",
- "type": "module",
- "main": "./src/index.ts",
- "exports": {
- ".": "./src/index.ts",
- "./escape": "./src/escape.ts",
- "./head": "./src/head.ts",
- "./body": "./src/body.ts"
- }
-}
diff --git a/package.json b/package.json
index c46088d..5fb6fe9 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,46 @@
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
+ },
+ "./escape": {
+ "import": {
+ "types": "./dist/escape.d.ts",
+ "default": "./dist/escape.js"
+ },
+ "require": {
+ "types": "./dist/escape.d.cts",
+ "default": "./dist/escape.cjs"
+ }
+ },
+ "./head": {
+ "import": {
+ "types": "./dist/head.d.ts",
+ "default": "./dist/head.js"
+ },
+ "require": {
+ "types": "./dist/head.d.cts",
+ "default": "./dist/head.cjs"
+ }
+ },
+ "./body": {
+ "import": {
+ "types": "./dist/body.d.ts",
+ "default": "./dist/body.js"
+ },
+ "require": {
+ "types": "./dist/body.d.cts",
+ "default": "./dist/body.cjs"
+ }
+ },
+ "./main": {
+ "import": {
+ "types": "./dist/main.d.ts",
+ "default": "./dist/main.js"
+ },
+ "require": {
+ "types": "./dist/main.d.cts",
+ "default": "./dist/main.cjs"
+ }
}
},
"files": [
@@ -85,6 +125,7 @@
"runtime",
"debug",
"llazyemail",
- "esm"
+ "esm",
+ "escape"
]
}
diff --git a/src/body.ts b/src/body.ts
index 90bca70..643f2d3 100644
--- a/src/body.ts
+++ b/src/body.ts
@@ -1,13 +1,20 @@
export interface BodyProps {
+ /** Raw HTML for the top of `` (e.g. hidden preheader). */
+ preheaderHtml?: string;
/** `` fragment. */
mainHtml?: string;
/** `` fragment. */
footerHtml?: string;
}
-export function body({ mainHtml = '', footerHtml = '' }: BodyProps = {}): string {
+export function body({
+ preheaderHtml = '',
+ mainHtml = '',
+ footerHtml = '',
+}: BodyProps = {}): string {
return `
+ ${preheaderHtml}
${mainHtml}
${footerHtml}
-`;
+ `;
}
diff --git a/src/escape.test.ts b/src/escape.test.ts
new file mode 100644
index 0000000..72481b0
--- /dev/null
+++ b/src/escape.test.ts
@@ -0,0 +1,73 @@
+import { describe, expect, it } from 'vitest';
+import { body, escapeHtml, head, main } from './index';
+
+describe('escapeHtml', () => {
+ it('escapes text and attribute characters', () => {
+ expect(escapeHtml(`Tom & Jerry