@react-email/render 1.0.3-canary.0 → 1.0.3-canary.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.js +19 -19
- package/dist/browser/index.mjs +19 -19
- package/dist/edge-light/index.d.mts +27 -0
- package/dist/edge-light/index.d.ts +27 -0
- package/dist/edge-light/index.js +216 -0
- package/dist/edge-light/index.mjs +180 -0
- package/dist/index.d.mts +27 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +144 -0
- package/dist/index.mjs +108 -0
- package/dist/node/index.js +21 -21
- package/dist/node/index.mjs +21 -21
- package/package.json +5 -5
package/dist/browser/index.js
CHANGED
|
@@ -75,16 +75,16 @@ var import_html_to_text = require("html-to-text");
|
|
|
75
75
|
var import_react = require("react");
|
|
76
76
|
|
|
77
77
|
// src/shared/utils/pretty.ts
|
|
78
|
-
var
|
|
78
|
+
var import_standalone = require("prettier/standalone");
|
|
79
|
+
var import_html = __toESM(require("prettier/plugins/html"));
|
|
79
80
|
var defaults = {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
sep: "\n"
|
|
81
|
+
endOfLine: "lf",
|
|
82
|
+
tabWidth: 2,
|
|
83
|
+
plugins: [import_html.default],
|
|
84
|
+
parser: "html"
|
|
85
85
|
};
|
|
86
86
|
var pretty = (str, options = {}) => {
|
|
87
|
-
return
|
|
87
|
+
return (0, import_standalone.format)(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
// src/shared/plain-text-selectors.ts
|
|
@@ -133,10 +133,10 @@ var readStream = (stream) => __async(void 0, null, function* () {
|
|
|
133
133
|
});
|
|
134
134
|
var render = (element, options) => __async(void 0, null, function* () {
|
|
135
135
|
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, { children: element });
|
|
136
|
-
const
|
|
137
|
-
let
|
|
136
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
137
|
+
let html2;
|
|
138
138
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
139
|
-
|
|
139
|
+
html2 = yield readStream(
|
|
140
140
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
141
141
|
);
|
|
142
142
|
} else {
|
|
@@ -144,7 +144,7 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
144
144
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
145
145
|
onAllReady() {
|
|
146
146
|
return __async(this, null, function* () {
|
|
147
|
-
|
|
147
|
+
html2 = yield readStream(stream);
|
|
148
148
|
resolve();
|
|
149
149
|
});
|
|
150
150
|
},
|
|
@@ -155,12 +155,12 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
157
|
if (options == null ? void 0 : options.plainText) {
|
|
158
|
-
return (0, import_html_to_text.convert)(
|
|
158
|
+
return (0, import_html_to_text.convert)(html2, __spreadValues({
|
|
159
159
|
selectors: plainTextSelectors
|
|
160
160
|
}, options.htmlToTextOptions));
|
|
161
161
|
}
|
|
162
162
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
163
|
-
const document = `${doctype}${
|
|
163
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
164
164
|
if (options == null ? void 0 : options.pretty) {
|
|
165
165
|
return pretty(document);
|
|
166
166
|
}
|
|
@@ -209,10 +209,10 @@ var readStream2 = (stream) => __async(void 0, null, function* () {
|
|
|
209
209
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
210
210
|
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
211
211
|
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { children: element });
|
|
212
|
-
const
|
|
213
|
-
let
|
|
212
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
213
|
+
let html2;
|
|
214
214
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
215
|
-
|
|
215
|
+
html2 = yield readStream2(
|
|
216
216
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
217
217
|
);
|
|
218
218
|
} else {
|
|
@@ -220,7 +220,7 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
220
220
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
221
221
|
onAllReady() {
|
|
222
222
|
return __async(this, null, function* () {
|
|
223
|
-
|
|
223
|
+
html2 = yield readStream2(stream);
|
|
224
224
|
resolve();
|
|
225
225
|
});
|
|
226
226
|
},
|
|
@@ -231,12 +231,12 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
233
|
if (options == null ? void 0 : options.plainText) {
|
|
234
|
-
return (0, import_html_to_text2.convert)(
|
|
234
|
+
return (0, import_html_to_text2.convert)(html2, __spreadValues({
|
|
235
235
|
selectors: plainTextSelectors
|
|
236
236
|
}, options.htmlToTextOptions));
|
|
237
237
|
}
|
|
238
238
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
239
|
-
const document = `${doctype}${
|
|
239
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
240
240
|
if (options == null ? void 0 : options.pretty) {
|
|
241
241
|
return pretty(document);
|
|
242
242
|
}
|
package/dist/browser/index.mjs
CHANGED
|
@@ -40,16 +40,16 @@ import { convert } from "html-to-text";
|
|
|
40
40
|
import { Suspense } from "react";
|
|
41
41
|
|
|
42
42
|
// src/shared/utils/pretty.ts
|
|
43
|
-
import
|
|
43
|
+
import { format } from "prettier/standalone";
|
|
44
|
+
import html from "prettier/plugins/html";
|
|
44
45
|
var defaults = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
sep: "\n"
|
|
46
|
+
endOfLine: "lf",
|
|
47
|
+
tabWidth: 2,
|
|
48
|
+
plugins: [html],
|
|
49
|
+
parser: "html"
|
|
50
50
|
};
|
|
51
51
|
var pretty = (str, options = {}) => {
|
|
52
|
-
return
|
|
52
|
+
return format(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
// src/shared/plain-text-selectors.ts
|
|
@@ -98,10 +98,10 @@ var readStream = (stream) => __async(void 0, null, function* () {
|
|
|
98
98
|
});
|
|
99
99
|
var render = (element, options) => __async(void 0, null, function* () {
|
|
100
100
|
const suspendedElement = /* @__PURE__ */ jsx(Suspense, { children: element });
|
|
101
|
-
const
|
|
102
|
-
let
|
|
101
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
102
|
+
let html2;
|
|
103
103
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
104
|
-
|
|
104
|
+
html2 = yield readStream(
|
|
105
105
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
106
106
|
);
|
|
107
107
|
} else {
|
|
@@ -109,7 +109,7 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
109
109
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
110
110
|
onAllReady() {
|
|
111
111
|
return __async(this, null, function* () {
|
|
112
|
-
|
|
112
|
+
html2 = yield readStream(stream);
|
|
113
113
|
resolve();
|
|
114
114
|
});
|
|
115
115
|
},
|
|
@@ -120,12 +120,12 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
120
120
|
});
|
|
121
121
|
}
|
|
122
122
|
if (options == null ? void 0 : options.plainText) {
|
|
123
|
-
return convert(
|
|
123
|
+
return convert(html2, __spreadValues({
|
|
124
124
|
selectors: plainTextSelectors
|
|
125
125
|
}, options.htmlToTextOptions));
|
|
126
126
|
}
|
|
127
127
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
128
|
-
const document = `${doctype}${
|
|
128
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
129
129
|
if (options == null ? void 0 : options.pretty) {
|
|
130
130
|
return pretty(document);
|
|
131
131
|
}
|
|
@@ -174,10 +174,10 @@ var readStream2 = (stream) => __async(void 0, null, function* () {
|
|
|
174
174
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
175
175
|
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
176
176
|
const suspendedElement = /* @__PURE__ */ jsx2(Suspense2, { children: element });
|
|
177
|
-
const
|
|
178
|
-
let
|
|
177
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
178
|
+
let html2;
|
|
179
179
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
180
|
-
|
|
180
|
+
html2 = yield readStream2(
|
|
181
181
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
182
182
|
);
|
|
183
183
|
} else {
|
|
@@ -185,7 +185,7 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
185
185
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
186
186
|
onAllReady() {
|
|
187
187
|
return __async(this, null, function* () {
|
|
188
|
-
|
|
188
|
+
html2 = yield readStream2(stream);
|
|
189
189
|
resolve();
|
|
190
190
|
});
|
|
191
191
|
},
|
|
@@ -196,12 +196,12 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
196
196
|
});
|
|
197
197
|
}
|
|
198
198
|
if (options == null ? void 0 : options.plainText) {
|
|
199
|
-
return convert2(
|
|
199
|
+
return convert2(html2, __spreadValues({
|
|
200
200
|
selectors: plainTextSelectors
|
|
201
201
|
}, options.htmlToTextOptions));
|
|
202
202
|
}
|
|
203
203
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
204
|
-
const document = `${doctype}${
|
|
204
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
205
205
|
if (options == null ? void 0 : options.pretty) {
|
|
206
206
|
return pretty(document);
|
|
207
207
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HtmlToTextOptions, SelectorDefinition } from 'html-to-text';
|
|
2
|
+
|
|
3
|
+
type Options = {
|
|
4
|
+
pretty?: boolean;
|
|
5
|
+
} & ({
|
|
6
|
+
plainText?: false;
|
|
7
|
+
} | {
|
|
8
|
+
plainText?: true;
|
|
9
|
+
/**
|
|
10
|
+
* These are options you can pass down directly to the library we use for
|
|
11
|
+
* converting the rendered email's HTML into plain text.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/html-to-text/node-html-to-text
|
|
14
|
+
*/
|
|
15
|
+
htmlToTextOptions?: HtmlToTextOptions;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated use `render`
|
|
22
|
+
*/
|
|
23
|
+
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
24
|
+
|
|
25
|
+
declare const plainTextSelectors: SelectorDefinition[];
|
|
26
|
+
|
|
27
|
+
export { Options, plainTextSelectors, render, renderAsync };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HtmlToTextOptions, SelectorDefinition } from 'html-to-text';
|
|
2
|
+
|
|
3
|
+
type Options = {
|
|
4
|
+
pretty?: boolean;
|
|
5
|
+
} & ({
|
|
6
|
+
plainText?: false;
|
|
7
|
+
} | {
|
|
8
|
+
plainText?: true;
|
|
9
|
+
/**
|
|
10
|
+
* These are options you can pass down directly to the library we use for
|
|
11
|
+
* converting the rendered email's HTML into plain text.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/html-to-text/node-html-to-text
|
|
14
|
+
*/
|
|
15
|
+
htmlToTextOptions?: HtmlToTextOptions;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated use `render`
|
|
22
|
+
*/
|
|
23
|
+
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
24
|
+
|
|
25
|
+
declare const plainTextSelectors: SelectorDefinition[];
|
|
26
|
+
|
|
27
|
+
export { Options, plainTextSelectors, render, renderAsync };
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __export = (target, all) => {
|
|
23
|
+
for (var name in all)
|
|
24
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
25
|
+
};
|
|
26
|
+
var __copyProps = (to, from, except, desc) => {
|
|
27
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
28
|
+
for (let key of __getOwnPropNames(from))
|
|
29
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
30
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
31
|
+
}
|
|
32
|
+
return to;
|
|
33
|
+
};
|
|
34
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
35
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
36
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
37
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
38
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
39
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
40
|
+
mod
|
|
41
|
+
));
|
|
42
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
43
|
+
var __async = (__this, __arguments, generator) => {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
var fulfilled = (value) => {
|
|
46
|
+
try {
|
|
47
|
+
step(generator.next(value));
|
|
48
|
+
} catch (e) {
|
|
49
|
+
reject(e);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var rejected = (value) => {
|
|
53
|
+
try {
|
|
54
|
+
step(generator.throw(value));
|
|
55
|
+
} catch (e) {
|
|
56
|
+
reject(e);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
60
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// src/edge-light/index.ts
|
|
65
|
+
var edge_light_exports = {};
|
|
66
|
+
__export(edge_light_exports, {
|
|
67
|
+
plainTextSelectors: () => plainTextSelectors,
|
|
68
|
+
render: () => render,
|
|
69
|
+
renderAsync: () => renderAsync
|
|
70
|
+
});
|
|
71
|
+
module.exports = __toCommonJS(edge_light_exports);
|
|
72
|
+
|
|
73
|
+
// src/edge-light/render.tsx
|
|
74
|
+
var import_html_to_text = require("html-to-text");
|
|
75
|
+
var import_react = require("react");
|
|
76
|
+
|
|
77
|
+
// src/shared/utils/pretty.ts
|
|
78
|
+
var import_js_beautify = __toESM(require("js-beautify"));
|
|
79
|
+
var defaults = {
|
|
80
|
+
unformatted: ["code", "pre", "em", "strong", "span"],
|
|
81
|
+
indent_inner_html: true,
|
|
82
|
+
indent_char: " ",
|
|
83
|
+
indent_size: 2,
|
|
84
|
+
sep: "\n"
|
|
85
|
+
};
|
|
86
|
+
var pretty = (str, options = {}) => {
|
|
87
|
+
return import_js_beautify.default.html(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// src/shared/plain-text-selectors.ts
|
|
91
|
+
var plainTextSelectors = [
|
|
92
|
+
{ selector: "img", format: "skip" },
|
|
93
|
+
{ selector: "#__react-email-preview", format: "skip" },
|
|
94
|
+
{
|
|
95
|
+
selector: "a",
|
|
96
|
+
options: { linkBrackets: false }
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// src/shared/read-stream.browser.ts
|
|
101
|
+
var decoder = new TextDecoder("utf-8");
|
|
102
|
+
var readStream = (stream) => __async(void 0, null, function* () {
|
|
103
|
+
const chunks = [];
|
|
104
|
+
if ("pipeTo" in stream) {
|
|
105
|
+
const writableStream = new WritableStream({
|
|
106
|
+
write(chunk) {
|
|
107
|
+
chunks.push(chunk);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
yield stream.pipeTo(writableStream);
|
|
111
|
+
} else {
|
|
112
|
+
throw new Error(
|
|
113
|
+
"For some reason, the Node version of `react-dom/server` has been imported instead of the browser one.",
|
|
114
|
+
{
|
|
115
|
+
cause: {
|
|
116
|
+
stream
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
let length = 0;
|
|
122
|
+
chunks.forEach((item) => {
|
|
123
|
+
length += item.length;
|
|
124
|
+
});
|
|
125
|
+
const mergedChunks = new Uint8Array(length);
|
|
126
|
+
let offset = 0;
|
|
127
|
+
chunks.forEach((item) => {
|
|
128
|
+
mergedChunks.set(item, offset);
|
|
129
|
+
offset += item.length;
|
|
130
|
+
});
|
|
131
|
+
return decoder.decode(mergedChunks);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// src/edge-light/render.tsx
|
|
135
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
136
|
+
var render = (element, options) => __async(void 0, null, function* () {
|
|
137
|
+
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, { children: element });
|
|
138
|
+
const { default: reactDOMServer } = yield import("react-dom/server.edge");
|
|
139
|
+
let html;
|
|
140
|
+
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
141
|
+
html = yield readStream(
|
|
142
|
+
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
143
|
+
);
|
|
144
|
+
} else {
|
|
145
|
+
yield new Promise((resolve, reject) => {
|
|
146
|
+
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
147
|
+
onAllReady() {
|
|
148
|
+
return __async(this, null, function* () {
|
|
149
|
+
html = yield readStream(stream);
|
|
150
|
+
resolve();
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
onError(error) {
|
|
154
|
+
reject(error);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (options == null ? void 0 : options.plainText) {
|
|
160
|
+
return (0, import_html_to_text.convert)(html, __spreadValues({
|
|
161
|
+
selectors: plainTextSelectors
|
|
162
|
+
}, options.htmlToTextOptions));
|
|
163
|
+
}
|
|
164
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
165
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
166
|
+
if (options == null ? void 0 : options.pretty) {
|
|
167
|
+
return pretty(document);
|
|
168
|
+
}
|
|
169
|
+
return document;
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// src/edge-light/render-async.tsx
|
|
173
|
+
var import_html_to_text2 = require("html-to-text");
|
|
174
|
+
var import_react2 = require("react");
|
|
175
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
176
|
+
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
177
|
+
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { children: element });
|
|
178
|
+
const { default: reactDOMServer } = yield import("react-dom/server.edge");
|
|
179
|
+
let html;
|
|
180
|
+
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
181
|
+
html = yield readStream(
|
|
182
|
+
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
183
|
+
);
|
|
184
|
+
} else {
|
|
185
|
+
yield new Promise((resolve, reject) => {
|
|
186
|
+
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
187
|
+
onAllReady() {
|
|
188
|
+
return __async(this, null, function* () {
|
|
189
|
+
html = yield readStream(stream);
|
|
190
|
+
resolve();
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
onError(error) {
|
|
194
|
+
reject(error);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (options == null ? void 0 : options.plainText) {
|
|
200
|
+
return (0, import_html_to_text2.convert)(html, __spreadValues({
|
|
201
|
+
selectors: plainTextSelectors
|
|
202
|
+
}, options.htmlToTextOptions));
|
|
203
|
+
}
|
|
204
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
205
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
206
|
+
if (options == null ? void 0 : options.pretty) {
|
|
207
|
+
return pretty(document);
|
|
208
|
+
}
|
|
209
|
+
return document;
|
|
210
|
+
});
|
|
211
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
212
|
+
0 && (module.exports = {
|
|
213
|
+
plainTextSelectors,
|
|
214
|
+
render,
|
|
215
|
+
renderAsync
|
|
216
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
var __async = (__this, __arguments, generator) => {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
var fulfilled = (value) => {
|
|
20
|
+
try {
|
|
21
|
+
step(generator.next(value));
|
|
22
|
+
} catch (e) {
|
|
23
|
+
reject(e);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var rejected = (value) => {
|
|
27
|
+
try {
|
|
28
|
+
step(generator.throw(value));
|
|
29
|
+
} catch (e) {
|
|
30
|
+
reject(e);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
34
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/edge-light/render.tsx
|
|
39
|
+
import { convert } from "html-to-text";
|
|
40
|
+
import { Suspense } from "react";
|
|
41
|
+
|
|
42
|
+
// src/shared/utils/pretty.ts
|
|
43
|
+
import jsBeautify from "js-beautify";
|
|
44
|
+
var defaults = {
|
|
45
|
+
unformatted: ["code", "pre", "em", "strong", "span"],
|
|
46
|
+
indent_inner_html: true,
|
|
47
|
+
indent_char: " ",
|
|
48
|
+
indent_size: 2,
|
|
49
|
+
sep: "\n"
|
|
50
|
+
};
|
|
51
|
+
var pretty = (str, options = {}) => {
|
|
52
|
+
return jsBeautify.html(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/shared/plain-text-selectors.ts
|
|
56
|
+
var plainTextSelectors = [
|
|
57
|
+
{ selector: "img", format: "skip" },
|
|
58
|
+
{ selector: "#__react-email-preview", format: "skip" },
|
|
59
|
+
{
|
|
60
|
+
selector: "a",
|
|
61
|
+
options: { linkBrackets: false }
|
|
62
|
+
}
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
// src/shared/read-stream.browser.ts
|
|
66
|
+
var decoder = new TextDecoder("utf-8");
|
|
67
|
+
var readStream = (stream) => __async(void 0, null, function* () {
|
|
68
|
+
const chunks = [];
|
|
69
|
+
if ("pipeTo" in stream) {
|
|
70
|
+
const writableStream = new WritableStream({
|
|
71
|
+
write(chunk) {
|
|
72
|
+
chunks.push(chunk);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
yield stream.pipeTo(writableStream);
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error(
|
|
78
|
+
"For some reason, the Node version of `react-dom/server` has been imported instead of the browser one.",
|
|
79
|
+
{
|
|
80
|
+
cause: {
|
|
81
|
+
stream
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
let length = 0;
|
|
87
|
+
chunks.forEach((item) => {
|
|
88
|
+
length += item.length;
|
|
89
|
+
});
|
|
90
|
+
const mergedChunks = new Uint8Array(length);
|
|
91
|
+
let offset = 0;
|
|
92
|
+
chunks.forEach((item) => {
|
|
93
|
+
mergedChunks.set(item, offset);
|
|
94
|
+
offset += item.length;
|
|
95
|
+
});
|
|
96
|
+
return decoder.decode(mergedChunks);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// src/edge-light/render.tsx
|
|
100
|
+
import { jsx } from "react/jsx-runtime";
|
|
101
|
+
var render = (element, options) => __async(void 0, null, function* () {
|
|
102
|
+
const suspendedElement = /* @__PURE__ */ jsx(Suspense, { children: element });
|
|
103
|
+
const { default: reactDOMServer } = yield import("react-dom/server.edge");
|
|
104
|
+
let html;
|
|
105
|
+
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
106
|
+
html = yield readStream(
|
|
107
|
+
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
yield new Promise((resolve, reject) => {
|
|
111
|
+
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
112
|
+
onAllReady() {
|
|
113
|
+
return __async(this, null, function* () {
|
|
114
|
+
html = yield readStream(stream);
|
|
115
|
+
resolve();
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
onError(error) {
|
|
119
|
+
reject(error);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (options == null ? void 0 : options.plainText) {
|
|
125
|
+
return convert(html, __spreadValues({
|
|
126
|
+
selectors: plainTextSelectors
|
|
127
|
+
}, options.htmlToTextOptions));
|
|
128
|
+
}
|
|
129
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
130
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
131
|
+
if (options == null ? void 0 : options.pretty) {
|
|
132
|
+
return pretty(document);
|
|
133
|
+
}
|
|
134
|
+
return document;
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// src/edge-light/render-async.tsx
|
|
138
|
+
import { convert as convert2 } from "html-to-text";
|
|
139
|
+
import { Suspense as Suspense2 } from "react";
|
|
140
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
141
|
+
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
142
|
+
const suspendedElement = /* @__PURE__ */ jsx2(Suspense2, { children: element });
|
|
143
|
+
const { default: reactDOMServer } = yield import("react-dom/server.edge");
|
|
144
|
+
let html;
|
|
145
|
+
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
146
|
+
html = yield readStream(
|
|
147
|
+
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
148
|
+
);
|
|
149
|
+
} else {
|
|
150
|
+
yield new Promise((resolve, reject) => {
|
|
151
|
+
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
152
|
+
onAllReady() {
|
|
153
|
+
return __async(this, null, function* () {
|
|
154
|
+
html = yield readStream(stream);
|
|
155
|
+
resolve();
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
onError(error) {
|
|
159
|
+
reject(error);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (options == null ? void 0 : options.plainText) {
|
|
165
|
+
return convert2(html, __spreadValues({
|
|
166
|
+
selectors: plainTextSelectors
|
|
167
|
+
}, options.htmlToTextOptions));
|
|
168
|
+
}
|
|
169
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
170
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
171
|
+
if (options == null ? void 0 : options.pretty) {
|
|
172
|
+
return pretty(document);
|
|
173
|
+
}
|
|
174
|
+
return document;
|
|
175
|
+
});
|
|
176
|
+
export {
|
|
177
|
+
plainTextSelectors,
|
|
178
|
+
render,
|
|
179
|
+
renderAsync
|
|
180
|
+
};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HtmlToTextOptions, SelectorDefinition } from 'html-to-text';
|
|
2
|
+
|
|
3
|
+
type Options = {
|
|
4
|
+
pretty?: boolean;
|
|
5
|
+
} & ({
|
|
6
|
+
plainText?: false;
|
|
7
|
+
} | {
|
|
8
|
+
plainText?: true;
|
|
9
|
+
/**
|
|
10
|
+
* These are options you can pass down directly to the library we use for
|
|
11
|
+
* converting the rendered email's HTML into plain text.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/html-to-text/node-html-to-text
|
|
14
|
+
*/
|
|
15
|
+
htmlToTextOptions?: HtmlToTextOptions;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated use `render`
|
|
22
|
+
*/
|
|
23
|
+
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
24
|
+
|
|
25
|
+
declare const plainTextSelectors: SelectorDefinition[];
|
|
26
|
+
|
|
27
|
+
export { Options, plainTextSelectors, render, renderAsync };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HtmlToTextOptions, SelectorDefinition } from 'html-to-text';
|
|
2
|
+
|
|
3
|
+
type Options = {
|
|
4
|
+
pretty?: boolean;
|
|
5
|
+
} & ({
|
|
6
|
+
plainText?: false;
|
|
7
|
+
} | {
|
|
8
|
+
plainText?: true;
|
|
9
|
+
/**
|
|
10
|
+
* These are options you can pass down directly to the library we use for
|
|
11
|
+
* converting the rendered email's HTML into plain text.
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/html-to-text/node-html-to-text
|
|
14
|
+
*/
|
|
15
|
+
htmlToTextOptions?: HtmlToTextOptions;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated use `render`
|
|
22
|
+
*/
|
|
23
|
+
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
24
|
+
|
|
25
|
+
declare const plainTextSelectors: SelectorDefinition[];
|
|
26
|
+
|
|
27
|
+
export { Options, plainTextSelectors, render, renderAsync };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __export = (target, all) => {
|
|
23
|
+
for (var name in all)
|
|
24
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
25
|
+
};
|
|
26
|
+
var __copyProps = (to, from, except, desc) => {
|
|
27
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
28
|
+
for (let key of __getOwnPropNames(from))
|
|
29
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
30
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
31
|
+
}
|
|
32
|
+
return to;
|
|
33
|
+
};
|
|
34
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
35
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
36
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
37
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
38
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
39
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
40
|
+
mod
|
|
41
|
+
));
|
|
42
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
43
|
+
var __async = (__this, __arguments, generator) => {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
var fulfilled = (value) => {
|
|
46
|
+
try {
|
|
47
|
+
step(generator.next(value));
|
|
48
|
+
} catch (e) {
|
|
49
|
+
reject(e);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var rejected = (value) => {
|
|
53
|
+
try {
|
|
54
|
+
step(generator.throw(value));
|
|
55
|
+
} catch (e) {
|
|
56
|
+
reject(e);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
60
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// src/index.ts
|
|
65
|
+
var src_exports = {};
|
|
66
|
+
__export(src_exports, {
|
|
67
|
+
plainTextSelectors: () => plainTextSelectors,
|
|
68
|
+
render: () => render,
|
|
69
|
+
renderAsync: () => renderAsync
|
|
70
|
+
});
|
|
71
|
+
module.exports = __toCommonJS(src_exports);
|
|
72
|
+
|
|
73
|
+
// src/render.tsx
|
|
74
|
+
var import_html_to_text = require("html-to-text");
|
|
75
|
+
var import_react_markup = require("react-markup");
|
|
76
|
+
var import_react = require("react");
|
|
77
|
+
|
|
78
|
+
// src/shared/utils/pretty.ts
|
|
79
|
+
var import_js_beautify = __toESM(require("js-beautify"));
|
|
80
|
+
var defaults = {
|
|
81
|
+
unformatted: ["code", "pre", "em", "strong", "span"],
|
|
82
|
+
indent_inner_html: true,
|
|
83
|
+
indent_char: " ",
|
|
84
|
+
indent_size: 2,
|
|
85
|
+
sep: "\n"
|
|
86
|
+
};
|
|
87
|
+
var pretty = (str, options = {}) => {
|
|
88
|
+
return import_js_beautify.default.html(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/shared/plain-text-selectors.ts
|
|
92
|
+
var plainTextSelectors = [
|
|
93
|
+
{ selector: "img", format: "skip" },
|
|
94
|
+
{ selector: "#__react-email-preview", format: "skip" },
|
|
95
|
+
{
|
|
96
|
+
selector: "a",
|
|
97
|
+
options: { linkBrackets: false }
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
// src/render.tsx
|
|
102
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
103
|
+
var render = (element, options) => __async(void 0, null, function* () {
|
|
104
|
+
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, { children: element });
|
|
105
|
+
const html = yield (0, import_react_markup.experimental_renderToHTML)(suspendedElement);
|
|
106
|
+
if (options == null ? void 0 : options.plainText) {
|
|
107
|
+
return (0, import_html_to_text.convert)(html, __spreadValues({
|
|
108
|
+
selectors: plainTextSelectors
|
|
109
|
+
}, options.htmlToTextOptions));
|
|
110
|
+
}
|
|
111
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
112
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
113
|
+
if (options == null ? void 0 : options.pretty) {
|
|
114
|
+
return pretty(document);
|
|
115
|
+
}
|
|
116
|
+
return document;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// src/render-async.tsx
|
|
120
|
+
var import_html_to_text2 = require("html-to-text");
|
|
121
|
+
var import_react2 = require("react");
|
|
122
|
+
var import_react_markup2 = require("react-markup");
|
|
123
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
124
|
+
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
125
|
+
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { children: element });
|
|
126
|
+
const html = yield (0, import_react_markup2.experimental_renderToHTML)(suspendedElement);
|
|
127
|
+
if (options == null ? void 0 : options.plainText) {
|
|
128
|
+
return (0, import_html_to_text2.convert)(html, __spreadValues({
|
|
129
|
+
selectors: plainTextSelectors
|
|
130
|
+
}, options.htmlToTextOptions));
|
|
131
|
+
}
|
|
132
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
133
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
134
|
+
if (options == null ? void 0 : options.pretty) {
|
|
135
|
+
return pretty(document);
|
|
136
|
+
}
|
|
137
|
+
return document;
|
|
138
|
+
});
|
|
139
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
140
|
+
0 && (module.exports = {
|
|
141
|
+
plainTextSelectors,
|
|
142
|
+
render,
|
|
143
|
+
renderAsync
|
|
144
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
var __async = (__this, __arguments, generator) => {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
var fulfilled = (value) => {
|
|
20
|
+
try {
|
|
21
|
+
step(generator.next(value));
|
|
22
|
+
} catch (e) {
|
|
23
|
+
reject(e);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var rejected = (value) => {
|
|
27
|
+
try {
|
|
28
|
+
step(generator.throw(value));
|
|
29
|
+
} catch (e) {
|
|
30
|
+
reject(e);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
34
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/render.tsx
|
|
39
|
+
import { convert } from "html-to-text";
|
|
40
|
+
import { experimental_renderToHTML as renderToHTML } from "react-markup";
|
|
41
|
+
import { Suspense } from "react";
|
|
42
|
+
|
|
43
|
+
// src/shared/utils/pretty.ts
|
|
44
|
+
import jsBeautify from "js-beautify";
|
|
45
|
+
var defaults = {
|
|
46
|
+
unformatted: ["code", "pre", "em", "strong", "span"],
|
|
47
|
+
indent_inner_html: true,
|
|
48
|
+
indent_char: " ",
|
|
49
|
+
indent_size: 2,
|
|
50
|
+
sep: "\n"
|
|
51
|
+
};
|
|
52
|
+
var pretty = (str, options = {}) => {
|
|
53
|
+
return jsBeautify.html(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/shared/plain-text-selectors.ts
|
|
57
|
+
var plainTextSelectors = [
|
|
58
|
+
{ selector: "img", format: "skip" },
|
|
59
|
+
{ selector: "#__react-email-preview", format: "skip" },
|
|
60
|
+
{
|
|
61
|
+
selector: "a",
|
|
62
|
+
options: { linkBrackets: false }
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
// src/render.tsx
|
|
67
|
+
import { jsx } from "react/jsx-runtime";
|
|
68
|
+
var render = (element, options) => __async(void 0, null, function* () {
|
|
69
|
+
const suspendedElement = /* @__PURE__ */ jsx(Suspense, { children: element });
|
|
70
|
+
const html = yield renderToHTML(suspendedElement);
|
|
71
|
+
if (options == null ? void 0 : options.plainText) {
|
|
72
|
+
return convert(html, __spreadValues({
|
|
73
|
+
selectors: plainTextSelectors
|
|
74
|
+
}, options.htmlToTextOptions));
|
|
75
|
+
}
|
|
76
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
77
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
78
|
+
if (options == null ? void 0 : options.pretty) {
|
|
79
|
+
return pretty(document);
|
|
80
|
+
}
|
|
81
|
+
return document;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// src/render-async.tsx
|
|
85
|
+
import { convert as convert2 } from "html-to-text";
|
|
86
|
+
import { Suspense as Suspense2 } from "react";
|
|
87
|
+
import { experimental_renderToHTML as renderToHTML2 } from "react-markup";
|
|
88
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
89
|
+
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
90
|
+
const suspendedElement = /* @__PURE__ */ jsx2(Suspense2, { children: element });
|
|
91
|
+
const html = yield renderToHTML2(suspendedElement);
|
|
92
|
+
if (options == null ? void 0 : options.plainText) {
|
|
93
|
+
return convert2(html, __spreadValues({
|
|
94
|
+
selectors: plainTextSelectors
|
|
95
|
+
}, options.htmlToTextOptions));
|
|
96
|
+
}
|
|
97
|
+
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
98
|
+
const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
99
|
+
if (options == null ? void 0 : options.pretty) {
|
|
100
|
+
return pretty(document);
|
|
101
|
+
}
|
|
102
|
+
return document;
|
|
103
|
+
});
|
|
104
|
+
export {
|
|
105
|
+
plainTextSelectors,
|
|
106
|
+
render,
|
|
107
|
+
renderAsync
|
|
108
|
+
};
|
package/dist/node/index.js
CHANGED
|
@@ -75,16 +75,16 @@ var import_html_to_text = require("html-to-text");
|
|
|
75
75
|
var import_react = require("react");
|
|
76
76
|
|
|
77
77
|
// src/shared/utils/pretty.ts
|
|
78
|
-
var
|
|
78
|
+
var import_standalone = require("prettier/standalone");
|
|
79
|
+
var import_html = __toESM(require("prettier/plugins/html"));
|
|
79
80
|
var defaults = {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
sep: "\n"
|
|
81
|
+
endOfLine: "lf",
|
|
82
|
+
tabWidth: 2,
|
|
83
|
+
plugins: [import_html.default],
|
|
84
|
+
parser: "html"
|
|
85
85
|
};
|
|
86
86
|
var pretty = (str, options = {}) => {
|
|
87
|
-
return
|
|
87
|
+
return (0, import_standalone.format)(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
// src/shared/plain-text-selectors.ts
|
|
@@ -117,10 +117,10 @@ var readStream = (stream) => __async(void 0, null, function* () {
|
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
stream.pipe(writable);
|
|
120
|
-
|
|
120
|
+
yield new Promise((resolve, reject) => {
|
|
121
121
|
writable.on("error", reject);
|
|
122
122
|
writable.on("close", () => {
|
|
123
|
-
resolve(
|
|
123
|
+
resolve();
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
126
|
}
|
|
@@ -131,10 +131,10 @@ var readStream = (stream) => __async(void 0, null, function* () {
|
|
|
131
131
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
132
132
|
var render = (element, options) => __async(void 0, null, function* () {
|
|
133
133
|
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, { children: element });
|
|
134
|
-
const
|
|
135
|
-
let
|
|
134
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
135
|
+
let html2;
|
|
136
136
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
137
|
-
|
|
137
|
+
html2 = yield readStream(
|
|
138
138
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
139
139
|
);
|
|
140
140
|
} else {
|
|
@@ -142,7 +142,7 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
142
142
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
143
143
|
onAllReady() {
|
|
144
144
|
return __async(this, null, function* () {
|
|
145
|
-
|
|
145
|
+
html2 = yield readStream(stream);
|
|
146
146
|
resolve();
|
|
147
147
|
});
|
|
148
148
|
},
|
|
@@ -153,12 +153,12 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
153
153
|
});
|
|
154
154
|
}
|
|
155
155
|
if (options == null ? void 0 : options.plainText) {
|
|
156
|
-
return (0, import_html_to_text.convert)(
|
|
156
|
+
return (0, import_html_to_text.convert)(html2, __spreadValues({
|
|
157
157
|
selectors: plainTextSelectors
|
|
158
158
|
}, options.htmlToTextOptions));
|
|
159
159
|
}
|
|
160
160
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
161
|
-
const document = `${doctype}${
|
|
161
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
162
162
|
if (options == null ? void 0 : options.pretty) {
|
|
163
163
|
return pretty(document);
|
|
164
164
|
}
|
|
@@ -171,10 +171,10 @@ var import_react2 = require("react");
|
|
|
171
171
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
172
172
|
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
173
173
|
const suspendedElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Suspense, { children: element });
|
|
174
|
-
const
|
|
175
|
-
let
|
|
174
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
175
|
+
let html2;
|
|
176
176
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
177
|
-
|
|
177
|
+
html2 = yield readStream(
|
|
178
178
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
179
179
|
);
|
|
180
180
|
} else {
|
|
@@ -182,7 +182,7 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
182
182
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
183
183
|
onAllReady() {
|
|
184
184
|
return __async(this, null, function* () {
|
|
185
|
-
|
|
185
|
+
html2 = yield readStream(stream);
|
|
186
186
|
resolve();
|
|
187
187
|
});
|
|
188
188
|
},
|
|
@@ -193,12 +193,12 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
193
193
|
});
|
|
194
194
|
}
|
|
195
195
|
if (options == null ? void 0 : options.plainText) {
|
|
196
|
-
return (0, import_html_to_text2.convert)(
|
|
196
|
+
return (0, import_html_to_text2.convert)(html2, __spreadValues({
|
|
197
197
|
selectors: plainTextSelectors
|
|
198
198
|
}, options.htmlToTextOptions));
|
|
199
199
|
}
|
|
200
200
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
201
|
-
const document = `${doctype}${
|
|
201
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
202
202
|
if (options == null ? void 0 : options.pretty) {
|
|
203
203
|
return pretty(document);
|
|
204
204
|
}
|
package/dist/node/index.mjs
CHANGED
|
@@ -40,16 +40,16 @@ import { convert } from "html-to-text";
|
|
|
40
40
|
import { Suspense } from "react";
|
|
41
41
|
|
|
42
42
|
// src/shared/utils/pretty.ts
|
|
43
|
-
import
|
|
43
|
+
import { format } from "prettier/standalone";
|
|
44
|
+
import html from "prettier/plugins/html";
|
|
44
45
|
var defaults = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
sep: "\n"
|
|
46
|
+
endOfLine: "lf",
|
|
47
|
+
tabWidth: 2,
|
|
48
|
+
plugins: [html],
|
|
49
|
+
parser: "html"
|
|
50
50
|
};
|
|
51
51
|
var pretty = (str, options = {}) => {
|
|
52
|
-
return
|
|
52
|
+
return format(str, __spreadValues(__spreadValues({}, defaults), options));
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
// src/shared/plain-text-selectors.ts
|
|
@@ -82,10 +82,10 @@ var readStream = (stream) => __async(void 0, null, function* () {
|
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
84
|
stream.pipe(writable);
|
|
85
|
-
|
|
85
|
+
yield new Promise((resolve, reject) => {
|
|
86
86
|
writable.on("error", reject);
|
|
87
87
|
writable.on("close", () => {
|
|
88
|
-
resolve(
|
|
88
|
+
resolve();
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
91
|
}
|
|
@@ -96,10 +96,10 @@ var readStream = (stream) => __async(void 0, null, function* () {
|
|
|
96
96
|
import { jsx } from "react/jsx-runtime";
|
|
97
97
|
var render = (element, options) => __async(void 0, null, function* () {
|
|
98
98
|
const suspendedElement = /* @__PURE__ */ jsx(Suspense, { children: element });
|
|
99
|
-
const
|
|
100
|
-
let
|
|
99
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
100
|
+
let html2;
|
|
101
101
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
102
|
-
|
|
102
|
+
html2 = yield readStream(
|
|
103
103
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
104
104
|
);
|
|
105
105
|
} else {
|
|
@@ -107,7 +107,7 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
107
107
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
108
108
|
onAllReady() {
|
|
109
109
|
return __async(this, null, function* () {
|
|
110
|
-
|
|
110
|
+
html2 = yield readStream(stream);
|
|
111
111
|
resolve();
|
|
112
112
|
});
|
|
113
113
|
},
|
|
@@ -118,12 +118,12 @@ var render = (element, options) => __async(void 0, null, function* () {
|
|
|
118
118
|
});
|
|
119
119
|
}
|
|
120
120
|
if (options == null ? void 0 : options.plainText) {
|
|
121
|
-
return convert(
|
|
121
|
+
return convert(html2, __spreadValues({
|
|
122
122
|
selectors: plainTextSelectors
|
|
123
123
|
}, options.htmlToTextOptions));
|
|
124
124
|
}
|
|
125
125
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
126
|
-
const document = `${doctype}${
|
|
126
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
127
127
|
if (options == null ? void 0 : options.pretty) {
|
|
128
128
|
return pretty(document);
|
|
129
129
|
}
|
|
@@ -136,10 +136,10 @@ import { Suspense as Suspense2 } from "react";
|
|
|
136
136
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
137
137
|
var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
138
138
|
const suspendedElement = /* @__PURE__ */ jsx2(Suspense2, { children: element });
|
|
139
|
-
const
|
|
140
|
-
let
|
|
139
|
+
const reactDOMServer = yield import("react-dom/server");
|
|
140
|
+
let html2;
|
|
141
141
|
if (Object.hasOwn(reactDOMServer, "renderToReadableStream")) {
|
|
142
|
-
|
|
142
|
+
html2 = yield readStream(
|
|
143
143
|
yield reactDOMServer.renderToReadableStream(suspendedElement)
|
|
144
144
|
);
|
|
145
145
|
} else {
|
|
@@ -147,7 +147,7 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
147
147
|
const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {
|
|
148
148
|
onAllReady() {
|
|
149
149
|
return __async(this, null, function* () {
|
|
150
|
-
|
|
150
|
+
html2 = yield readStream(stream);
|
|
151
151
|
resolve();
|
|
152
152
|
});
|
|
153
153
|
},
|
|
@@ -158,12 +158,12 @@ var renderAsync = (element, options) => __async(void 0, null, function* () {
|
|
|
158
158
|
});
|
|
159
159
|
}
|
|
160
160
|
if (options == null ? void 0 : options.plainText) {
|
|
161
|
-
return convert2(
|
|
161
|
+
return convert2(html2, __spreadValues({
|
|
162
162
|
selectors: plainTextSelectors
|
|
163
163
|
}, options.htmlToTextOptions));
|
|
164
164
|
}
|
|
165
165
|
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
|
|
166
|
-
const document = `${doctype}${
|
|
166
|
+
const document = `${doctype}${html2.replace(/<!DOCTYPE.*?>/, "")}`;
|
|
167
167
|
if (options == null ? void 0 : options.pretty) {
|
|
168
168
|
return pretty(document);
|
|
169
169
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-email/render",
|
|
3
|
-
"version": "1.0.3-canary.
|
|
3
|
+
"version": "1.0.3-canary.2",
|
|
4
4
|
"description": "Transform React components into HTML email templates",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/browser/index.js",
|
|
@@ -78,17 +78,17 @@
|
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"html-to-text": "9.0.5",
|
|
81
|
-
"
|
|
81
|
+
"prettier": "3.3.3",
|
|
82
82
|
"react": "^18.0 || ^19.0 || ^19.0.0-rc",
|
|
83
83
|
"react-dom": "^18.0 || ^19.0 || ^19.0.0-rc",
|
|
84
84
|
"react-promise-suspense": "0.3.4"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
|
-
"@types/react": "npm:types-react@19.0.0-rc.1",
|
|
88
|
-
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
|
89
87
|
"@edge-runtime/vm": "3.1.8",
|
|
90
88
|
"@types/html-to-text": "9.0.4",
|
|
91
|
-
"@types/
|
|
89
|
+
"@types/prettier": "3.0.0",
|
|
90
|
+
"@types/react": "npm:types-react@19.0.0-rc.1",
|
|
91
|
+
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
|
92
92
|
"jsdom": "23.0.1",
|
|
93
93
|
"tsup": "7.2.0",
|
|
94
94
|
"typescript": "5.1.6",
|