@react-email/render 1.4.0 → 2.0.0-canary.1
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.d.mts +4 -10
- package/dist/browser/index.d.mts.map +1 -1
- package/dist/browser/index.d.ts +4 -10
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +2 -12
- package/dist/browser/index.mjs +2 -11
- package/dist/browser/index.mjs.map +1 -1
- package/dist/edge/index.d.mts +4 -10
- package/dist/edge/index.d.mts.map +1 -1
- package/dist/edge/index.d.ts +4 -10
- package/dist/edge/index.d.ts.map +1 -1
- package/dist/edge/index.js +2 -12
- package/dist/edge/index.mjs +2 -11
- package/dist/edge/index.mjs.map +1 -1
- package/dist/node/index.d.mts +4 -10
- package/dist/node/index.d.mts.map +1 -1
- package/dist/node/index.d.ts +4 -10
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -12
- package/dist/node/index.mjs +2 -11
- package/dist/node/index.mjs.map +1 -1
- package/package.json +3 -5
package/dist/browser/index.d.mts
CHANGED
|
@@ -4,17 +4,17 @@ import { Options as Options$1 } from "prettier";
|
|
|
4
4
|
//#region src/shared/options.d.ts
|
|
5
5
|
type Options = {
|
|
6
6
|
/**
|
|
7
|
-
* @
|
|
7
|
+
* @see {@link pretty}
|
|
8
8
|
*/
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
} & ({
|
|
11
11
|
/**
|
|
12
|
-
* @
|
|
12
|
+
* @see {@link toPlainText}
|
|
13
13
|
*/
|
|
14
14
|
plainText?: false;
|
|
15
15
|
} | {
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @see {@link toPlainText}
|
|
18
18
|
*/
|
|
19
19
|
plainText?: true;
|
|
20
20
|
/**
|
|
@@ -36,11 +36,5 @@ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
|
|
|
36
36
|
//#region src/browser/render.d.ts
|
|
37
37
|
declare const render: (node: React.ReactNode, options?: Options) => Promise<string>;
|
|
38
38
|
//#endregion
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated use {@link render}
|
|
42
|
-
*/
|
|
43
|
-
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { Options, plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
39
|
+
export { Options, plainTextSelectors, pretty, render, toPlainText };
|
|
46
40
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/browser/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/browser/render.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,OAAA;;;AAAZ;;;;AC0FA;;;;ECxFa;AASb;;;;ACVA;;;;;sBHsB0B;;;;cCmEb,gCAAgC,cAAY;;;cCxF5C,oBAAoB;iBASjB,WAAA,yBAAoC;;;cCVvC,eAAsB,KAAA,CAAM,qBAAqB,YAAO"}
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -4,17 +4,17 @@ import { Options as Options$1 } from "prettier";
|
|
|
4
4
|
//#region src/shared/options.d.ts
|
|
5
5
|
type Options = {
|
|
6
6
|
/**
|
|
7
|
-
* @
|
|
7
|
+
* @see {@link pretty}
|
|
8
8
|
*/
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
} & ({
|
|
11
11
|
/**
|
|
12
|
-
* @
|
|
12
|
+
* @see {@link toPlainText}
|
|
13
13
|
*/
|
|
14
14
|
plainText?: false;
|
|
15
15
|
} | {
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @see {@link toPlainText}
|
|
18
18
|
*/
|
|
19
19
|
plainText?: true;
|
|
20
20
|
/**
|
|
@@ -36,11 +36,5 @@ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
|
|
|
36
36
|
//#region src/browser/render.d.ts
|
|
37
37
|
declare const render: (node: React.ReactNode, options?: Options) => Promise<string>;
|
|
38
38
|
//#endregion
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated use {@link render}
|
|
42
|
-
*/
|
|
43
|
-
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { Options, plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
39
|
+
export { Options, plainTextSelectors, pretty, render, toPlainText };
|
|
46
40
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/browser/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/browser/render.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,OAAA;;;AAAZ;;;;AC0FA;;;;ECxFa;AASb;;;;ACVA;;;;;sBHsB0B;;;;cCmEb,gCAAgC,cAAY;;;cCxF5C,oBAAoB;iBASjB,WAAA,yBAAoC;;;cCVvC,eAAsB,KAAA,CAAM,qBAAqB,YAAO"}
|
package/dist/browser/index.js
CHANGED
|
@@ -21,14 +21,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
let react = require("react");
|
|
25
|
-
react = __toESM(react);
|
|
26
24
|
let prettier_plugins_html = require("prettier/plugins/html");
|
|
27
25
|
prettier_plugins_html = __toESM(prettier_plugins_html);
|
|
28
26
|
let prettier_standalone = require("prettier/standalone");
|
|
29
27
|
prettier_standalone = __toESM(prettier_standalone);
|
|
30
28
|
let html_to_text = require("html-to-text");
|
|
31
29
|
html_to_text = __toESM(html_to_text);
|
|
30
|
+
let react = require("react");
|
|
31
|
+
react = __toESM(react);
|
|
32
32
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
33
33
|
react_jsx_runtime = __toESM(react_jsx_runtime);
|
|
34
34
|
|
|
@@ -157,18 +157,8 @@ const render = async (node, options) => {
|
|
|
157
157
|
return document;
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
//#endregion
|
|
161
|
-
//#region src/browser/index.ts
|
|
162
|
-
/**
|
|
163
|
-
* @deprecated use {@link render}
|
|
164
|
-
*/
|
|
165
|
-
const renderAsync = (element, options) => {
|
|
166
|
-
return render(element, options);
|
|
167
|
-
};
|
|
168
|
-
|
|
169
160
|
//#endregion
|
|
170
161
|
exports.plainTextSelectors = plainTextSelectors;
|
|
171
162
|
exports.pretty = pretty;
|
|
172
163
|
exports.render = render;
|
|
173
|
-
exports.renderAsync = renderAsync;
|
|
174
164
|
exports.toPlainText = toPlainText;
|
package/dist/browser/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Suspense } from "react";
|
|
2
1
|
import * as html from "prettier/plugins/html";
|
|
3
2
|
import { format } from "prettier/standalone";
|
|
4
3
|
import { convert } from "html-to-text";
|
|
4
|
+
import { Suspense } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/shared/utils/pretty.ts
|
|
@@ -130,14 +130,5 @@ const render = async (node, options) => {
|
|
|
130
130
|
};
|
|
131
131
|
|
|
132
132
|
//#endregion
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* @deprecated use {@link render}
|
|
136
|
-
*/
|
|
137
|
-
const renderAsync = (element, options) => {
|
|
138
|
-
return render(element, options);
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
//#endregion
|
|
142
|
-
export { plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
133
|
+
export { plainTextSelectors, pretty, render, toPlainText };
|
|
143
134
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defaults: Options","plainTextSelectors: SelectorDefinition[]","html","chunks: Uint8Array[]","html"],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/shared/read-stream.browser.ts","../../src/browser/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defaults: Options","plainTextSelectors: SelectorDefinition[]","html","chunks: Uint8Array[]","html"],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/shared/read-stream.browser.ts","../../src/browser/render.tsx"],"sourcesContent":["import type { Options, Plugin } from 'prettier';\nimport type { builders } from 'prettier/doc';\nimport * as html from 'prettier/plugins/html';\nimport { format } from 'prettier/standalone';\n\ninterface HtmlNode {\n type: 'element' | 'text' | 'ieConditionalComment';\n name?: string;\n sourceSpan: {\n start: { file: unknown[]; offset: number; line: number; col: number };\n end: { file: unknown[]; offset: number; line: number; col: number };\n details: null;\n };\n parent?: HtmlNode;\n}\n\nfunction recursivelyMapDoc(\n doc: builders.Doc,\n callback: (innerDoc: string | builders.DocCommand) => builders.Doc,\n): builders.Doc {\n if (Array.isArray(doc)) {\n return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));\n }\n\n if (typeof doc === 'object') {\n if (doc.type === 'group') {\n return {\n ...doc,\n contents: recursivelyMapDoc(doc.contents, callback),\n expandedStates: recursivelyMapDoc(\n doc.expandedStates,\n callback,\n ) as builders.Doc[],\n };\n }\n\n if ('contents' in doc) {\n return {\n ...doc,\n contents: recursivelyMapDoc(doc.contents, callback),\n };\n }\n\n if ('parts' in doc) {\n return {\n ...doc,\n parts: recursivelyMapDoc(doc.parts, callback) as builders.Doc[],\n };\n }\n\n if (doc.type === 'if-break') {\n return {\n ...doc,\n breakContents: recursivelyMapDoc(doc.breakContents, callback),\n flatContents: recursivelyMapDoc(doc.flatContents, callback),\n };\n }\n }\n\n return callback(doc);\n}\n\nconst modifiedHtml = { ...html } as Plugin;\nif (modifiedHtml.printers) {\n const previousPrint = modifiedHtml.printers.html.print;\n modifiedHtml.printers.html.print = (path, options, print, args) => {\n const node = path.getNode() as HtmlNode;\n\n const rawPrintingResult = previousPrint(path, options, print, args);\n\n if (node.type === 'ieConditionalComment') {\n const printingResult = recursivelyMapDoc(rawPrintingResult, (doc) => {\n if (typeof doc === 'object' && doc.type === 'line') {\n return doc.soft ? '' : ' ';\n }\n\n return doc;\n });\n\n return printingResult;\n }\n\n return rawPrintingResult;\n };\n}\n\nconst defaults: Options = {\n endOfLine: 'lf',\n tabWidth: 2,\n plugins: [modifiedHtml],\n bracketSameLine: true,\n parser: 'html',\n};\n\nexport const pretty = (str: string, options: Options = {}) => {\n return format(str.replaceAll('\\0', ''), {\n ...defaults,\n ...options,\n });\n};\n","import {\n convert,\n type HtmlToTextOptions,\n type SelectorDefinition,\n} from 'html-to-text';\n\nexport const plainTextSelectors: SelectorDefinition[] = [\n { selector: 'img', format: 'skip' },\n { selector: '[data-skip-in-text=true]', format: 'skip' },\n {\n selector: 'a',\n options: { linkBrackets: false, hideLinkHrefIfSameAsText: true },\n },\n];\n\nexport function toPlainText(html: string, options?: HtmlToTextOptions) {\n return convert(html, {\n selectors: plainTextSelectors,\n wordwrap: false,\n ...options,\n });\n}\n","import type { ReactDOMServerReadableStream } from 'react-dom/server.browser';\n\nconst decoder = new TextDecoder('utf-8');\n\nexport const readStream = async (stream: ReactDOMServerReadableStream) => {\n const chunks: Uint8Array[] = [];\n\n const writableStream = new WritableStream({\n write(chunk: Uint8Array) {\n chunks.push(chunk);\n },\n abort(reason) {\n throw new Error('Stream aborted', {\n cause: {\n reason,\n },\n });\n },\n });\n await stream.pipeTo(writableStream);\n\n let length = 0;\n chunks.forEach((item) => {\n length += item.length;\n });\n const mergedChunks = new Uint8Array(length);\n let offset = 0;\n chunks.forEach((item) => {\n mergedChunks.set(item, offset);\n offset += item.length;\n });\n\n return decoder.decode(mergedChunks);\n};\n","import { Suspense } from 'react';\nimport { pretty, toPlainText } from '../node';\nimport type { Options } from '../shared/options';\nimport { readStream } from '../shared/read-stream.browser';\n\nexport const render = async (node: React.ReactNode, options?: Options) => {\n const suspendedElement = <Suspense>{node}</Suspense>;\n const reactDOMServer = await import('react-dom/server.browser').then(\n // This is beacuse react-dom/server is CJS\n (m) => m.default,\n );\n\n const html = await new Promise<string>((resolve, reject) => {\n reactDOMServer\n .renderToReadableStream(suspendedElement, {\n onError(error: unknown) {\n reject(error);\n },\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n })\n .then(readStream)\n .then(resolve)\n .catch(reject);\n });\n\n if (options?.plainText) {\n return toPlainText(html, options.htmlToTextOptions);\n }\n\n const doctype =\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';\n\n const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, '')}`;\n\n if (options?.pretty) {\n return pretty(document);\n }\n\n return document;\n};\n"],"mappings":"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"}
|
package/dist/edge/index.d.mts
CHANGED
|
@@ -4,17 +4,17 @@ import { Options as Options$1 } from "prettier";
|
|
|
4
4
|
//#region src/shared/options.d.ts
|
|
5
5
|
type Options = {
|
|
6
6
|
/**
|
|
7
|
-
* @
|
|
7
|
+
* @see {@link pretty}
|
|
8
8
|
*/
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
} & ({
|
|
11
11
|
/**
|
|
12
|
-
* @
|
|
12
|
+
* @see {@link toPlainText}
|
|
13
13
|
*/
|
|
14
14
|
plainText?: false;
|
|
15
15
|
} | {
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @see {@link toPlainText}
|
|
18
18
|
*/
|
|
19
19
|
plainText?: true;
|
|
20
20
|
/**
|
|
@@ -36,11 +36,5 @@ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
|
|
|
36
36
|
//#region src/edge/render.d.ts
|
|
37
37
|
declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
38
38
|
//#endregion
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated use {@link render}
|
|
42
|
-
*/
|
|
43
|
-
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { Options, plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
39
|
+
export { Options, plainTextSelectors, pretty, render, toPlainText };
|
|
46
40
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/edge/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/edge/render.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,OAAA;;;AAAZ;;;;AC0FA;;;;ECxFa;AASb;;;;ACRA;;;;;sBHoB0B;;;;cCmEb,gCAAgC,cAAY;;;cCxF5C,oBAAoB;iBASjB,WAAA,yBAAoC;;;cCRvC,kBACF,KAAA,CAAM,wBACL,YAAO"}
|
package/dist/edge/index.d.ts
CHANGED
|
@@ -4,17 +4,17 @@ import { Options as Options$1 } from "prettier";
|
|
|
4
4
|
//#region src/shared/options.d.ts
|
|
5
5
|
type Options = {
|
|
6
6
|
/**
|
|
7
|
-
* @
|
|
7
|
+
* @see {@link pretty}
|
|
8
8
|
*/
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
} & ({
|
|
11
11
|
/**
|
|
12
|
-
* @
|
|
12
|
+
* @see {@link toPlainText}
|
|
13
13
|
*/
|
|
14
14
|
plainText?: false;
|
|
15
15
|
} | {
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @see {@link toPlainText}
|
|
18
18
|
*/
|
|
19
19
|
plainText?: true;
|
|
20
20
|
/**
|
|
@@ -36,11 +36,5 @@ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
|
|
|
36
36
|
//#region src/edge/render.d.ts
|
|
37
37
|
declare const render: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
38
38
|
//#endregion
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated use {@link render}
|
|
42
|
-
*/
|
|
43
|
-
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { Options, plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
39
|
+
export { Options, plainTextSelectors, pretty, render, toPlainText };
|
|
46
40
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/edge/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/edge/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/edge/render.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,OAAA;;;AAAZ;;;;AC0FA;;;;ECxFa;AASb;;;;ACRA;;;;;sBHoB0B;;;;cCmEb,gCAAgC,cAAY;;;cCxF5C,oBAAoB;iBASjB,WAAA,yBAAoC;;;cCRvC,kBACF,KAAA,CAAM,wBACL,YAAO"}
|
package/dist/edge/index.js
CHANGED
|
@@ -21,14 +21,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
let react = require("react");
|
|
25
|
-
react = __toESM(react);
|
|
26
24
|
let prettier_plugins_html = require("prettier/plugins/html");
|
|
27
25
|
prettier_plugins_html = __toESM(prettier_plugins_html);
|
|
28
26
|
let prettier_standalone = require("prettier/standalone");
|
|
29
27
|
prettier_standalone = __toESM(prettier_standalone);
|
|
30
28
|
let html_to_text = require("html-to-text");
|
|
31
29
|
html_to_text = __toESM(html_to_text);
|
|
30
|
+
let react = require("react");
|
|
31
|
+
react = __toESM(react);
|
|
32
32
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
33
33
|
react_jsx_runtime = __toESM(react_jsx_runtime);
|
|
34
34
|
|
|
@@ -163,18 +163,8 @@ const render = async (element, options) => {
|
|
|
163
163
|
return document;
|
|
164
164
|
};
|
|
165
165
|
|
|
166
|
-
//#endregion
|
|
167
|
-
//#region src/edge/index.ts
|
|
168
|
-
/**
|
|
169
|
-
* @deprecated use {@link render}
|
|
170
|
-
*/
|
|
171
|
-
const renderAsync = (element, options) => {
|
|
172
|
-
return render(element, options);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
166
|
//#endregion
|
|
176
167
|
exports.plainTextSelectors = plainTextSelectors;
|
|
177
168
|
exports.pretty = pretty;
|
|
178
169
|
exports.render = render;
|
|
179
|
-
exports.renderAsync = renderAsync;
|
|
180
170
|
exports.toPlainText = toPlainText;
|
package/dist/edge/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Suspense } from "react";
|
|
2
1
|
import * as html from "prettier/plugins/html";
|
|
3
2
|
import { format } from "prettier/standalone";
|
|
4
3
|
import { convert } from "html-to-text";
|
|
4
|
+
import { Suspense } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/shared/utils/pretty.ts
|
|
@@ -136,14 +136,5 @@ const render = async (element, options) => {
|
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
//#endregion
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* @deprecated use {@link render}
|
|
142
|
-
*/
|
|
143
|
-
const renderAsync = (element, options) => {
|
|
144
|
-
return render(element, options);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
//#endregion
|
|
148
|
-
export { plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
139
|
+
export { plainTextSelectors, pretty, render, toPlainText };
|
|
149
140
|
//# sourceMappingURL=index.mjs.map
|
package/dist/edge/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defaults: Options","plainTextSelectors: SelectorDefinition[]","html","chunks: Uint8Array[]","html"],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/shared/read-stream.browser.ts","../../src/edge/import-react-dom.tsx","../../src/edge/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defaults: Options","plainTextSelectors: SelectorDefinition[]","html","chunks: Uint8Array[]","html"],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/shared/read-stream.browser.ts","../../src/edge/import-react-dom.tsx","../../src/edge/render.tsx"],"sourcesContent":["import type { Options, Plugin } from 'prettier';\nimport type { builders } from 'prettier/doc';\nimport * as html from 'prettier/plugins/html';\nimport { format } from 'prettier/standalone';\n\ninterface HtmlNode {\n type: 'element' | 'text' | 'ieConditionalComment';\n name?: string;\n sourceSpan: {\n start: { file: unknown[]; offset: number; line: number; col: number };\n end: { file: unknown[]; offset: number; line: number; col: number };\n details: null;\n };\n parent?: HtmlNode;\n}\n\nfunction recursivelyMapDoc(\n doc: builders.Doc,\n callback: (innerDoc: string | builders.DocCommand) => builders.Doc,\n): builders.Doc {\n if (Array.isArray(doc)) {\n return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));\n }\n\n if (typeof doc === 'object') {\n if (doc.type === 'group') {\n return {\n ...doc,\n contents: recursivelyMapDoc(doc.contents, callback),\n expandedStates: recursivelyMapDoc(\n doc.expandedStates,\n callback,\n ) as builders.Doc[],\n };\n }\n\n if ('contents' in doc) {\n return {\n ...doc,\n contents: recursivelyMapDoc(doc.contents, callback),\n };\n }\n\n if ('parts' in doc) {\n return {\n ...doc,\n parts: recursivelyMapDoc(doc.parts, callback) as builders.Doc[],\n };\n }\n\n if (doc.type === 'if-break') {\n return {\n ...doc,\n breakContents: recursivelyMapDoc(doc.breakContents, callback),\n flatContents: recursivelyMapDoc(doc.flatContents, callback),\n };\n }\n }\n\n return callback(doc);\n}\n\nconst modifiedHtml = { ...html } as Plugin;\nif (modifiedHtml.printers) {\n const previousPrint = modifiedHtml.printers.html.print;\n modifiedHtml.printers.html.print = (path, options, print, args) => {\n const node = path.getNode() as HtmlNode;\n\n const rawPrintingResult = previousPrint(path, options, print, args);\n\n if (node.type === 'ieConditionalComment') {\n const printingResult = recursivelyMapDoc(rawPrintingResult, (doc) => {\n if (typeof doc === 'object' && doc.type === 'line') {\n return doc.soft ? '' : ' ';\n }\n\n return doc;\n });\n\n return printingResult;\n }\n\n return rawPrintingResult;\n };\n}\n\nconst defaults: Options = {\n endOfLine: 'lf',\n tabWidth: 2,\n plugins: [modifiedHtml],\n bracketSameLine: true,\n parser: 'html',\n};\n\nexport const pretty = (str: string, options: Options = {}) => {\n return format(str.replaceAll('\\0', ''), {\n ...defaults,\n ...options,\n });\n};\n","import {\n convert,\n type HtmlToTextOptions,\n type SelectorDefinition,\n} from 'html-to-text';\n\nexport const plainTextSelectors: SelectorDefinition[] = [\n { selector: 'img', format: 'skip' },\n { selector: '[data-skip-in-text=true]', format: 'skip' },\n {\n selector: 'a',\n options: { linkBrackets: false, hideLinkHrefIfSameAsText: true },\n },\n];\n\nexport function toPlainText(html: string, options?: HtmlToTextOptions) {\n return convert(html, {\n selectors: plainTextSelectors,\n wordwrap: false,\n ...options,\n });\n}\n","import type { ReactDOMServerReadableStream } from 'react-dom/server.browser';\n\nconst decoder = new TextDecoder('utf-8');\n\nexport const readStream = async (stream: ReactDOMServerReadableStream) => {\n const chunks: Uint8Array[] = [];\n\n const writableStream = new WritableStream({\n write(chunk: Uint8Array) {\n chunks.push(chunk);\n },\n abort(reason) {\n throw new Error('Stream aborted', {\n cause: {\n reason,\n },\n });\n },\n });\n await stream.pipeTo(writableStream);\n\n let length = 0;\n chunks.forEach((item) => {\n length += item.length;\n });\n const mergedChunks = new Uint8Array(length);\n let offset = 0;\n chunks.forEach((item) => {\n mergedChunks.set(item, offset);\n offset += item.length;\n });\n\n return decoder.decode(mergedChunks);\n};\n","export const importReactDom = () => {\n // We don't use async here because tsup converts it to a generator syntax\n // that esbuild doesn't understand as dealing with the import failing during\n // bundling: https://github.com/evanw/esbuild/issues/3216#issuecomment-1628913722\n return import('react-dom/server.edge').catch(\n () =>\n // This ensures that we still have compatibility with React 18,\n // which doesn't have the `.edge` export.\n import('react-dom/server'),\n );\n};\n","import { Suspense } from 'react';\nimport { pretty } from '../node';\nimport type { Options } from '../shared/options';\nimport { readStream } from '../shared/read-stream.browser';\nimport { toPlainText } from '../shared/utils/to-plain-text';\nimport { importReactDom } from './import-react-dom';\n\nexport const render = async (\n element: React.ReactElement,\n options?: Options,\n) => {\n const suspendedElement = <Suspense>{element}</Suspense>;\n const reactDOMServer = await importReactDom().then(\n // This is because react-dom/server is CJS\n (m) => m.default,\n );\n\n const html = await new Promise<string>((resolve, reject) => {\n reactDOMServer\n .renderToReadableStream(suspendedElement, {\n onError(error: unknown) {\n reject(error);\n },\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n })\n .then(readStream)\n .then(resolve)\n .catch(reject);\n });\n\n if (options?.plainText) {\n return toPlainText(html, options.htmlToTextOptions);\n }\n\n const doctype =\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';\n\n const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, '')}`;\n\n if (options?.pretty) {\n return pretty(document);\n }\n\n return document;\n};\n"],"mappings":"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"}
|
package/dist/node/index.d.mts
CHANGED
|
@@ -4,17 +4,17 @@ import { Options as Options$1 } from "prettier";
|
|
|
4
4
|
//#region src/shared/options.d.ts
|
|
5
5
|
type Options = {
|
|
6
6
|
/**
|
|
7
|
-
* @
|
|
7
|
+
* @see {@link pretty}
|
|
8
8
|
*/
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
} & ({
|
|
11
11
|
/**
|
|
12
|
-
* @
|
|
12
|
+
* @see {@link toPlainText}
|
|
13
13
|
*/
|
|
14
14
|
plainText?: false;
|
|
15
15
|
} | {
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @see {@link toPlainText}
|
|
18
18
|
*/
|
|
19
19
|
plainText?: true;
|
|
20
20
|
/**
|
|
@@ -36,11 +36,5 @@ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
|
|
|
36
36
|
//#region src/node/render.d.ts
|
|
37
37
|
declare const render: (node: React.ReactNode, options?: Options) => Promise<string>;
|
|
38
38
|
//#endregion
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated use {@link render}
|
|
42
|
-
*/
|
|
43
|
-
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { Options, plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
39
|
+
export { Options, plainTextSelectors, pretty, render, toPlainText };
|
|
46
40
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/node/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/node/render.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,OAAA;;;AAAZ;;;;AC0FA;;;;ECxFa;AASb;;;;ACTA;;;;;sBHqB0B;;;;cCmEb,gCAAgC,cAAY;;;cCxF5C,oBAAoB;iBASjB,WAAA,yBAAoC;;;cCTvC,eAAsB,KAAA,CAAM,qBAAqB,YAAO"}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -4,17 +4,17 @@ import { Options as Options$1 } from "prettier";
|
|
|
4
4
|
//#region src/shared/options.d.ts
|
|
5
5
|
type Options = {
|
|
6
6
|
/**
|
|
7
|
-
* @
|
|
7
|
+
* @see {@link pretty}
|
|
8
8
|
*/
|
|
9
9
|
pretty?: boolean;
|
|
10
10
|
} & ({
|
|
11
11
|
/**
|
|
12
|
-
* @
|
|
12
|
+
* @see {@link toPlainText}
|
|
13
13
|
*/
|
|
14
14
|
plainText?: false;
|
|
15
15
|
} | {
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @see {@link toPlainText}
|
|
18
18
|
*/
|
|
19
19
|
plainText?: true;
|
|
20
20
|
/**
|
|
@@ -36,11 +36,5 @@ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
|
|
|
36
36
|
//#region src/node/render.d.ts
|
|
37
37
|
declare const render: (node: React.ReactNode, options?: Options) => Promise<string>;
|
|
38
38
|
//#endregion
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* @deprecated use {@link render}
|
|
42
|
-
*/
|
|
43
|
-
declare const renderAsync: (element: React.ReactElement, options?: Options) => Promise<string>;
|
|
44
|
-
//#endregion
|
|
45
|
-
export { Options, plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
39
|
+
export { Options, plainTextSelectors, pretty, render, toPlainText };
|
|
46
40
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/node/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/node/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/node/render.tsx"],"sourcesContent":[],"mappings":";;;;KAIY,OAAA;;;AAAZ;;;;AC0FA;;;;ECxFa;AASb;;;;ACTA;;;;;sBHqB0B;;;;cCmEb,gCAAgC,cAAY;;;cCxF5C,oBAAoB;iBASjB,WAAA,yBAAoC;;;cCTvC,eAAsB,KAAA,CAAM,qBAAqB,YAAO"}
|
package/dist/node/index.js
CHANGED
|
@@ -21,14 +21,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
let react = require("react");
|
|
25
|
-
react = __toESM(react);
|
|
26
24
|
let prettier_plugins_html = require("prettier/plugins/html");
|
|
27
25
|
prettier_plugins_html = __toESM(prettier_plugins_html);
|
|
28
26
|
let prettier_standalone = require("prettier/standalone");
|
|
29
27
|
prettier_standalone = __toESM(prettier_standalone);
|
|
30
28
|
let html_to_text = require("html-to-text");
|
|
31
29
|
html_to_text = __toESM(html_to_text);
|
|
30
|
+
let react = require("react");
|
|
31
|
+
react = __toESM(react);
|
|
32
32
|
let node_stream = require("node:stream");
|
|
33
33
|
node_stream = __toESM(node_stream);
|
|
34
34
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -175,18 +175,8 @@ const render = async (node, options) => {
|
|
|
175
175
|
return document;
|
|
176
176
|
};
|
|
177
177
|
|
|
178
|
-
//#endregion
|
|
179
|
-
//#region src/node/index.ts
|
|
180
|
-
/**
|
|
181
|
-
* @deprecated use {@link render}
|
|
182
|
-
*/
|
|
183
|
-
const renderAsync = (element, options) => {
|
|
184
|
-
return render(element, options);
|
|
185
|
-
};
|
|
186
|
-
|
|
187
178
|
//#endregion
|
|
188
179
|
exports.plainTextSelectors = plainTextSelectors;
|
|
189
180
|
exports.pretty = pretty;
|
|
190
181
|
exports.render = render;
|
|
191
|
-
exports.renderAsync = renderAsync;
|
|
192
182
|
exports.toPlainText = toPlainText;
|
package/dist/node/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Suspense } from "react";
|
|
2
1
|
import * as html from "prettier/plugins/html";
|
|
3
2
|
import { format } from "prettier/standalone";
|
|
4
3
|
import { convert } from "html-to-text";
|
|
4
|
+
import { Suspense } from "react";
|
|
5
5
|
import { Writable } from "node:stream";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
|
|
@@ -147,14 +147,5 @@ const render = async (node, options) => {
|
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
//#endregion
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* @deprecated use {@link render}
|
|
153
|
-
*/
|
|
154
|
-
const renderAsync = (element, options) => {
|
|
155
|
-
return render(element, options);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
//#endregion
|
|
159
|
-
export { plainTextSelectors, pretty, render, renderAsync, toPlainText };
|
|
150
|
+
export { plainTextSelectors, pretty, render, toPlainText };
|
|
160
151
|
//# sourceMappingURL=index.mjs.map
|
package/dist/node/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["defaults: Options","plainTextSelectors: SelectorDefinition[]","html","html!: string","html"],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/node/read-stream.ts","../../src/node/render.tsx"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["defaults: Options","plainTextSelectors: SelectorDefinition[]","html","html!: string","html"],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/node/read-stream.ts","../../src/node/render.tsx"],"sourcesContent":["import type { Options, Plugin } from 'prettier';\nimport type { builders } from 'prettier/doc';\nimport * as html from 'prettier/plugins/html';\nimport { format } from 'prettier/standalone';\n\ninterface HtmlNode {\n type: 'element' | 'text' | 'ieConditionalComment';\n name?: string;\n sourceSpan: {\n start: { file: unknown[]; offset: number; line: number; col: number };\n end: { file: unknown[]; offset: number; line: number; col: number };\n details: null;\n };\n parent?: HtmlNode;\n}\n\nfunction recursivelyMapDoc(\n doc: builders.Doc,\n callback: (innerDoc: string | builders.DocCommand) => builders.Doc,\n): builders.Doc {\n if (Array.isArray(doc)) {\n return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));\n }\n\n if (typeof doc === 'object') {\n if (doc.type === 'group') {\n return {\n ...doc,\n contents: recursivelyMapDoc(doc.contents, callback),\n expandedStates: recursivelyMapDoc(\n doc.expandedStates,\n callback,\n ) as builders.Doc[],\n };\n }\n\n if ('contents' in doc) {\n return {\n ...doc,\n contents: recursivelyMapDoc(doc.contents, callback),\n };\n }\n\n if ('parts' in doc) {\n return {\n ...doc,\n parts: recursivelyMapDoc(doc.parts, callback) as builders.Doc[],\n };\n }\n\n if (doc.type === 'if-break') {\n return {\n ...doc,\n breakContents: recursivelyMapDoc(doc.breakContents, callback),\n flatContents: recursivelyMapDoc(doc.flatContents, callback),\n };\n }\n }\n\n return callback(doc);\n}\n\nconst modifiedHtml = { ...html } as Plugin;\nif (modifiedHtml.printers) {\n const previousPrint = modifiedHtml.printers.html.print;\n modifiedHtml.printers.html.print = (path, options, print, args) => {\n const node = path.getNode() as HtmlNode;\n\n const rawPrintingResult = previousPrint(path, options, print, args);\n\n if (node.type === 'ieConditionalComment') {\n const printingResult = recursivelyMapDoc(rawPrintingResult, (doc) => {\n if (typeof doc === 'object' && doc.type === 'line') {\n return doc.soft ? '' : ' ';\n }\n\n return doc;\n });\n\n return printingResult;\n }\n\n return rawPrintingResult;\n };\n}\n\nconst defaults: Options = {\n endOfLine: 'lf',\n tabWidth: 2,\n plugins: [modifiedHtml],\n bracketSameLine: true,\n parser: 'html',\n};\n\nexport const pretty = (str: string, options: Options = {}) => {\n return format(str.replaceAll('\\0', ''), {\n ...defaults,\n ...options,\n });\n};\n","import {\n convert,\n type HtmlToTextOptions,\n type SelectorDefinition,\n} from 'html-to-text';\n\nexport const plainTextSelectors: SelectorDefinition[] = [\n { selector: 'img', format: 'skip' },\n { selector: '[data-skip-in-text=true]', format: 'skip' },\n {\n selector: 'a',\n options: { linkBrackets: false, hideLinkHrefIfSameAsText: true },\n },\n];\n\nexport function toPlainText(html: string, options?: HtmlToTextOptions) {\n return convert(html, {\n selectors: plainTextSelectors,\n wordwrap: false,\n ...options,\n });\n}\n","import { Writable } from 'node:stream';\nimport type {\n PipeableStream,\n ReactDOMServerReadableStream,\n} from 'react-dom/server.browser';\n\nexport const readStream = async (\n stream: PipeableStream | ReactDOMServerReadableStream,\n) => {\n let result = '';\n // Create a single TextDecoder instance to handle streaming properly\n // This fixes issues with multi-byte characters (e.g., CJK) being split across chunks\n const decoder = new TextDecoder('utf-8');\n\n if ('pipeTo' in stream) {\n // means it's a readable stream\n const writableStream = new WritableStream({\n write(chunk: BufferSource) {\n // Use stream: true to handle multi-byte characters split across chunks\n result += decoder.decode(chunk, { stream: true });\n },\n close() {\n // Flush any remaining bytes\n result += decoder.decode();\n },\n });\n await stream.pipeTo(writableStream);\n } else {\n const writable = new Writable({\n write(chunk: BufferSource, _encoding, callback) {\n // Use stream: true to handle multi-byte characters split across chunks\n result += decoder.decode(chunk, { stream: true });\n\n callback();\n },\n final(callback) {\n // Flush any remaining bytes\n result += decoder.decode();\n callback();\n },\n });\n stream.pipe(writable);\n\n await new Promise<void>((resolve, reject) => {\n writable.on('error', reject);\n writable.on('close', () => {\n resolve();\n });\n });\n }\n\n return result;\n};\n","import { Suspense } from 'react';\nimport type { Options } from '../shared/options';\nimport { pretty } from '../shared/utils/pretty';\nimport { toPlainText } from '../shared/utils/to-plain-text';\nimport { readStream } from './read-stream';\n\nexport const render = async (node: React.ReactNode, options?: Options) => {\n const suspendedElement = <Suspense>{node}</Suspense>;\n const reactDOMServer = await import('react-dom/server').then(\n // This is beacuse react-dom/server is CJS\n (m) => m.default,\n );\n\n let html!: string;\n if (\n Object.hasOwn(reactDOMServer, 'renderToReadableStream') &&\n typeof WritableStream !== 'undefined'\n ) {\n html = await readStream(\n await reactDOMServer.renderToReadableStream(suspendedElement, {\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n }),\n );\n } else {\n await new Promise<void>((resolve, reject) => {\n const stream = reactDOMServer.renderToPipeableStream(suspendedElement, {\n async onAllReady() {\n html = await readStream(stream);\n resolve();\n },\n onError(error) {\n reject(error as Error);\n },\n progressiveChunkSize: Number.POSITIVE_INFINITY,\n });\n });\n }\n\n if (options?.plainText) {\n return toPlainText(html, options.htmlToTextOptions);\n }\n\n const doctype =\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';\n\n const document = `${doctype}${html.replace(/<!DOCTYPE.*?>/, '')}`;\n\n if (options?.pretty) {\n return pretty(document);\n }\n\n return document;\n};\n"],"mappings":";;;;;;;;AAgBA,SAAS,kBACP,KACA,UACc;AACd,KAAI,MAAM,QAAQ,IAAI,CACpB,QAAO,IAAI,KAAK,aAAa,kBAAkB,UAAU,SAAS,CAAC;AAGrE,KAAI,OAAO,QAAQ,UAAU;AAC3B,MAAI,IAAI,SAAS,QACf,QAAO;GACL,GAAG;GACH,UAAU,kBAAkB,IAAI,UAAU,SAAS;GACnD,gBAAgB,kBACd,IAAI,gBACJ,SACD;GACF;AAGH,MAAI,cAAc,IAChB,QAAO;GACL,GAAG;GACH,UAAU,kBAAkB,IAAI,UAAU,SAAS;GACpD;AAGH,MAAI,WAAW,IACb,QAAO;GACL,GAAG;GACH,OAAO,kBAAkB,IAAI,OAAO,SAAS;GAC9C;AAGH,MAAI,IAAI,SAAS,WACf,QAAO;GACL,GAAG;GACH,eAAe,kBAAkB,IAAI,eAAe,SAAS;GAC7D,cAAc,kBAAkB,IAAI,cAAc,SAAS;GAC5D;;AAIL,QAAO,SAAS,IAAI;;AAGtB,MAAM,eAAe,EAAE,GAAG,MAAM;AAChC,IAAI,aAAa,UAAU;CACzB,MAAM,gBAAgB,aAAa,SAAS,KAAK;AACjD,cAAa,SAAS,KAAK,SAAS,MAAM,SAAS,OAAO,SAAS;EACjE,MAAM,OAAO,KAAK,SAAS;EAE3B,MAAM,oBAAoB,cAAc,MAAM,SAAS,OAAO,KAAK;AAEnE,MAAI,KAAK,SAAS,uBAShB,QARuB,kBAAkB,oBAAoB,QAAQ;AACnE,OAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,OAC1C,QAAO,IAAI,OAAO,KAAK;AAGzB,UAAO;IACP;AAKJ,SAAO;;;AAIX,MAAMA,WAAoB;CACxB,WAAW;CACX,UAAU;CACV,SAAS,CAAC,aAAa;CACvB,iBAAiB;CACjB,QAAQ;CACT;AAED,MAAa,UAAU,KAAa,UAAmB,EAAE,KAAK;AAC5D,QAAO,OAAO,IAAI,WAAW,MAAM,GAAG,EAAE;EACtC,GAAG;EACH,GAAG;EACJ,CAAC;;;;;AC5FJ,MAAaC,qBAA2C;CACtD;EAAE,UAAU;EAAO,QAAQ;EAAQ;CACnC;EAAE,UAAU;EAA4B,QAAQ;EAAQ;CACxD;EACE,UAAU;EACV,SAAS;GAAE,cAAc;GAAO,0BAA0B;GAAM;EACjE;CACF;AAED,SAAgB,YAAY,QAAc,SAA6B;AACrE,QAAO,QAAQC,QAAM;EACnB,WAAW;EACX,UAAU;EACV,GAAG;EACJ,CAAC;;;;;ACdJ,MAAa,aAAa,OACxB,WACG;CACH,IAAI,SAAS;CAGb,MAAM,UAAU,IAAI,YAAY,QAAQ;AAExC,KAAI,YAAY,QAAQ;EAEtB,MAAM,iBAAiB,IAAI,eAAe;GACxC,MAAM,OAAqB;AAEzB,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;;GAEnD,QAAQ;AAEN,cAAU,QAAQ,QAAQ;;GAE7B,CAAC;AACF,QAAM,OAAO,OAAO,eAAe;QAC9B;EACL,MAAM,WAAW,IAAI,SAAS;GAC5B,MAAM,OAAqB,WAAW,UAAU;AAE9C,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;AAEjD,cAAU;;GAEZ,MAAM,UAAU;AAEd,cAAU,QAAQ,QAAQ;AAC1B,cAAU;;GAEb,CAAC;AACF,SAAO,KAAK,SAAS;AAErB,QAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,YAAS,GAAG,SAAS,OAAO;AAC5B,YAAS,GAAG,eAAe;AACzB,aAAS;KACT;IACF;;AAGJ,QAAO;;;;;AC7CT,MAAa,SAAS,OAAO,MAAuB,YAAsB;CACxE,MAAM,mBAAmB,oBAAC,sBAAU,OAAgB;CACpD,MAAM,iBAAiB,MAAM,OAAO,oBAAoB,MAErD,MAAM,EAAE,QACV;CAED,IAAIC;AACJ,KACE,OAAO,OAAO,gBAAgB,yBAAyB,IACvD,OAAO,mBAAmB,YAE1B,UAAO,MAAM,WACX,MAAM,eAAe,uBAAuB,kBAAkB,EAC5D,sBAAsB,OAAO,mBAC9B,CAAC,CACH;KAED,OAAM,IAAI,SAAe,SAAS,WAAW;EAC3C,MAAM,SAAS,eAAe,uBAAuB,kBAAkB;GACrE,MAAM,aAAa;AACjB,aAAO,MAAM,WAAW,OAAO;AAC/B,aAAS;;GAEX,QAAQ,OAAO;AACb,WAAO,MAAe;;GAExB,sBAAsB,OAAO;GAC9B,CAAC;GACF;AAGJ,KAAI,SAAS,UACX,QAAO,YAAYC,QAAM,QAAQ,kBAAkB;CAMrD,MAAM,WAAW,4HAAaA,OAAK,QAAQ,iBAAiB,GAAG;AAE/D,KAAI,SAAS,OACX,QAAO,OAAO,SAAS;AAGzB,QAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-email/render",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-canary.1",
|
|
4
4
|
"description": "Transform React components into HTML email templates",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/browser/index.js",
|
|
@@ -104,12 +104,11 @@
|
|
|
104
104
|
"email"
|
|
105
105
|
],
|
|
106
106
|
"engines": {
|
|
107
|
-
"node": ">=
|
|
107
|
+
"node": ">=22.0.0"
|
|
108
108
|
},
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"html-to-text": "^9.0.5",
|
|
111
|
-
"prettier": "^3.5.3"
|
|
112
|
-
"react-promise-suspense": "^0.3.4"
|
|
111
|
+
"prettier": "^3.5.3"
|
|
113
112
|
},
|
|
114
113
|
"peerDependencies": {
|
|
115
114
|
"react": "^18.0 || ^19.0 || ^19.0.0-rc",
|
|
@@ -118,7 +117,6 @@
|
|
|
118
117
|
"devDependencies": {
|
|
119
118
|
"@edge-runtime/vm": "5.0.0",
|
|
120
119
|
"@types/html-to-text": "9.0.4",
|
|
121
|
-
"@types/prettier": "3.0.0",
|
|
122
120
|
"@types/react": "npm:types-react@19.0.0-rc.1",
|
|
123
121
|
"@types/react-dom": "npm:types-react-dom@19.0.0",
|
|
124
122
|
"jsdom": "26.1.0",
|