@solid-email/render 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ainul Yaqin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,161 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let solid_js_web_dist_server_js = require("solid-js/web/dist/server.js");
25
+ let prettier_plugins_html = require("prettier/plugins/html");
26
+ prettier_plugins_html = __toESM(prettier_plugins_html, 1);
27
+ let prettier_standalone = require("prettier/standalone");
28
+ let html_to_text = require("html-to-text");
29
+ //#region src/shared/utils/pretty.ts
30
+ function getHtmlNode(path) {
31
+ const topNode = path.node;
32
+ if (topNode) return topNode;
33
+ return path.stack?.[path.stack.length - 1];
34
+ }
35
+ function recursivelyMapDoc(doc, callback) {
36
+ if (Array.isArray(doc)) return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));
37
+ if (typeof doc === "object") {
38
+ if (doc.type === "line") return callback(doc.soft ? "" : " ");
39
+ if (doc.type === "group") return {
40
+ ...doc,
41
+ contents: recursivelyMapDoc(doc.contents, callback),
42
+ expandedStates: recursivelyMapDoc(doc.expandedStates, callback)
43
+ };
44
+ if ("contents" in doc) return {
45
+ ...doc,
46
+ contents: recursivelyMapDoc(doc.contents, callback)
47
+ };
48
+ if ("parts" in doc) return {
49
+ ...doc,
50
+ parts: recursivelyMapDoc(doc.parts, callback)
51
+ };
52
+ if (doc.type === "if-break") return {
53
+ ...doc,
54
+ breakContents: recursivelyMapDoc(doc.breakContents, callback),
55
+ flatContents: recursivelyMapDoc(doc.flatContents, callback)
56
+ };
57
+ const nextDoc = { ...doc };
58
+ for (const [key, value] of Object.entries(nextDoc)) if (value && typeof value === "object") nextDoc[key] = recursivelyMapDoc(value, callback);
59
+ return nextDoc;
60
+ }
61
+ return callback(doc);
62
+ }
63
+ const modifiedHtml = { ...prettier_plugins_html };
64
+ const htmlPrinter = modifiedHtml.printers?.html;
65
+ if (htmlPrinter?.print) {
66
+ const previousPrint = htmlPrinter.print;
67
+ htmlPrinter.print = (path, options, print, args) => {
68
+ const node = getHtmlNode(path);
69
+ const rawPrintingResult = previousPrint(path, options, print, args);
70
+ if (node?.type === "ieConditionalComment" || node?.kind === "ieConditionalComment") return recursivelyMapDoc(rawPrintingResult, (doc) => {
71
+ if (typeof doc === "object" && doc.type === "line") return doc.soft ? "" : " ";
72
+ return doc;
73
+ });
74
+ return rawPrintingResult;
75
+ };
76
+ }
77
+ const defaults = {
78
+ endOfLine: "lf",
79
+ tabWidth: 2,
80
+ plugins: [modifiedHtml],
81
+ bracketSameLine: true,
82
+ parser: "html"
83
+ };
84
+ const pretty = (str, options = {}) => {
85
+ return (0, prettier_standalone.format)(str.replaceAll("\0", ""), {
86
+ ...defaults,
87
+ ...options
88
+ });
89
+ };
90
+ //#endregion
91
+ //#region src/shared/utils/to-plain-text.ts
92
+ const plainTextSelectors = [
93
+ {
94
+ selector: "img",
95
+ format: "skip"
96
+ },
97
+ {
98
+ selector: "[data-skip-in-text=true]",
99
+ format: "skip"
100
+ },
101
+ {
102
+ selector: "a",
103
+ options: {
104
+ linkBrackets: false,
105
+ hideLinkHrefIfSameAsText: true
106
+ }
107
+ }
108
+ ];
109
+ function toPlainText(html, options) {
110
+ return (0, html_to_text.convert)(html, {
111
+ wordwrap: false,
112
+ ...options,
113
+ selectors: [...plainTextSelectors, ...options?.selectors ?? []]
114
+ });
115
+ }
116
+ //#endregion
117
+ //#region src/shared/render.ts
118
+ const doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
119
+ function normalizeRenderable(node) {
120
+ return typeof node === "function" ? node : () => node;
121
+ }
122
+ function decodeSerializedString(value) {
123
+ try {
124
+ const jsonSafe = value.replace(/\\x([0-9A-Fa-f]{2})/g, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
125
+ const parsed = JSON.parse(`"${jsonSafe}"`);
126
+ return typeof parsed === "string" ? parsed : value;
127
+ } catch {
128
+ return value;
129
+ }
130
+ }
131
+ function removeSolidResourceScripts(html) {
132
+ const errorMatch = /Object\.assign\(new Error\("((?:\\.|[^"\\])*)"\)/.exec(html);
133
+ if (errorMatch) throw new Error(decodeSerializedString(errorMatch[1] ?? ""));
134
+ return html.replace(/<script>self\.\$R=self\.\$R\|\|\[\];[\s\S]*?<\/script>/g, "");
135
+ }
136
+ function renderDocument(html) {
137
+ return `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
138
+ }
139
+ function renderSyncOutput(html, options) {
140
+ if (options?.plainText) return toPlainText(html, options.htmlToTextOptions);
141
+ return renderDocument(html);
142
+ }
143
+ async function renderOutput(html, options) {
144
+ if (options?.plainText) return toPlainText(html, options.htmlToTextOptions);
145
+ const document = renderDocument(html);
146
+ if (options?.pretty) return pretty(document);
147
+ return document;
148
+ }
149
+ async function render(node, options) {
150
+ return renderOutput(removeSolidResourceScripts(await (0, solid_js_web_dist_server_js.renderToStringAsync)(normalizeRenderable(node))), options);
151
+ }
152
+ function renderSync(node, options) {
153
+ if (options?.pretty) throw new Error("renderSync does not support pretty output; use render.");
154
+ return renderSyncOutput(removeSolidResourceScripts((0, solid_js_web_dist_server_js.renderToString)(normalizeRenderable(node))), options);
155
+ }
156
+ //#endregion
157
+ exports.plainTextSelectors = plainTextSelectors;
158
+ exports.pretty = pretty;
159
+ exports.render = render;
160
+ exports.renderSync = renderSync;
161
+ exports.toPlainText = toPlainText;
@@ -0,0 +1,34 @@
1
+ import { HtmlToTextOptions, SelectorDefinition } from "html-to-text";
2
+ import { JSX } from "solid-js";
3
+ import { Options as Options$1 } from "prettier";
4
+
5
+ //#region src/shared/options.d.ts
6
+ type PlainTextDisabled = {
7
+ plainText?: false;
8
+ };
9
+ type PlainTextEnabled = {
10
+ plainText?: true;
11
+ htmlToTextOptions?: HtmlToTextOptions;
12
+ };
13
+ type PlainTextOptions = PlainTextDisabled | PlainTextEnabled;
14
+ type Options = {
15
+ pretty?: boolean;
16
+ } & PlainTextOptions;
17
+ type RenderSyncOptions = {
18
+ pretty?: false;
19
+ } & PlainTextOptions;
20
+ //#endregion
21
+ //#region src/shared/render.d.ts
22
+ type Renderable = JSX.Element | (() => JSX.Element);
23
+ declare function render(node: Renderable, options?: Options): Promise<string>;
24
+ declare function renderSync(node: Renderable, options?: RenderSyncOptions): string;
25
+ //#endregion
26
+ //#region src/shared/utils/pretty.d.ts
27
+ declare const pretty: (str: string, options?: Options$1) => Promise<string>;
28
+ //#endregion
29
+ //#region src/shared/utils/to-plain-text.d.ts
30
+ declare const plainTextSelectors: SelectorDefinition[];
31
+ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
32
+ //#endregion
33
+ export { Options, RenderSyncOptions, Renderable, plainTextSelectors, pretty, render, renderSync, toPlainText };
34
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/render.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts"],"mappings":";;;;;KAEK,iBAAA;EACH,SAAS;AAAA;AAAA,KAGN,gBAAA;EACH,SAAA;EACA,iBAAA,GAAoB,iBAAiB;AAAA;AAAA,KAGlC,gBAAA,GAAmB,iBAAA,GAAoB,gBAAgB;AAAA,KAEhD,OAAA;EACV,MAAA;AAAA,IACE,gBAAgB;AAAA,KAER,iBAAA;EACV,MAAA;AAAA,IACE,gBAAgB;;;KCVR,UAAA,GAAa,GAAA,CAAI,OAAA,UAAiB,GAAA,CAAI,OAAO;AAAA,iBA+DnC,MAAA,CACpB,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,OAAA,GACT,OAAA;AAAA,iBAQa,UAAA,CACd,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,iBAAiB;;;cCuChB,MAAA,GAAU,GAAA,UAAa,OAAA,GAAS,SAAA,KAAY,OAAA;;;cCpH5C,kBAAA,EAAoB,kBAAkB;AAAA,iBASnC,WAAA,CAAY,IAAA,UAAc,OAAA,GAAU,iBAAiB"}
@@ -0,0 +1,34 @@
1
+ import { HtmlToTextOptions, SelectorDefinition } from "html-to-text";
2
+ import { JSX } from "solid-js";
3
+ import { Options as Options$1 } from "prettier";
4
+
5
+ //#region src/shared/options.d.ts
6
+ type PlainTextDisabled = {
7
+ plainText?: false;
8
+ };
9
+ type PlainTextEnabled = {
10
+ plainText?: true;
11
+ htmlToTextOptions?: HtmlToTextOptions;
12
+ };
13
+ type PlainTextOptions = PlainTextDisabled | PlainTextEnabled;
14
+ type Options = {
15
+ pretty?: boolean;
16
+ } & PlainTextOptions;
17
+ type RenderSyncOptions = {
18
+ pretty?: false;
19
+ } & PlainTextOptions;
20
+ //#endregion
21
+ //#region src/shared/render.d.ts
22
+ type Renderable = JSX.Element | (() => JSX.Element);
23
+ declare function render(node: Renderable, options?: Options): Promise<string>;
24
+ declare function renderSync(node: Renderable, options?: RenderSyncOptions): string;
25
+ //#endregion
26
+ //#region src/shared/utils/pretty.d.ts
27
+ declare const pretty: (str: string, options?: Options$1) => Promise<string>;
28
+ //#endregion
29
+ //#region src/shared/utils/to-plain-text.d.ts
30
+ declare const plainTextSelectors: SelectorDefinition[];
31
+ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
32
+ //#endregion
33
+ export { Options, RenderSyncOptions, Renderable, plainTextSelectors, pretty, render, renderSync, toPlainText };
34
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/render.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts"],"mappings":";;;;;KAEK,iBAAA;EACH,SAAS;AAAA;AAAA,KAGN,gBAAA;EACH,SAAA;EACA,iBAAA,GAAoB,iBAAiB;AAAA;AAAA,KAGlC,gBAAA,GAAmB,iBAAA,GAAoB,gBAAgB;AAAA,KAEhD,OAAA;EACV,MAAA;AAAA,IACE,gBAAgB;AAAA,KAER,iBAAA;EACV,MAAA;AAAA,IACE,gBAAgB;;;KCVR,UAAA,GAAa,GAAA,CAAI,OAAA,UAAiB,GAAA,CAAI,OAAO;AAAA,iBA+DnC,MAAA,CACpB,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,OAAA,GACT,OAAA;AAAA,iBAQa,UAAA,CACd,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,iBAAiB;;;cCuChB,MAAA,GAAU,GAAA,UAAa,OAAA,GAAS,SAAA,KAAY,OAAA;;;cCpH5C,kBAAA,EAAoB,kBAAkB;AAAA,iBASnC,WAAA,CAAY,IAAA,UAAc,OAAA,GAAU,iBAAiB"}
@@ -0,0 +1,135 @@
1
+ import { renderToString, renderToStringAsync } from "solid-js/web/dist/server.js";
2
+ import * as html from "prettier/plugins/html";
3
+ import { format } from "prettier/standalone";
4
+ import { convert } from "html-to-text";
5
+ //#region src/shared/utils/pretty.ts
6
+ function getHtmlNode(path) {
7
+ const topNode = path.node;
8
+ if (topNode) return topNode;
9
+ return path.stack?.[path.stack.length - 1];
10
+ }
11
+ function recursivelyMapDoc(doc, callback) {
12
+ if (Array.isArray(doc)) return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));
13
+ if (typeof doc === "object") {
14
+ if (doc.type === "line") return callback(doc.soft ? "" : " ");
15
+ if (doc.type === "group") return {
16
+ ...doc,
17
+ contents: recursivelyMapDoc(doc.contents, callback),
18
+ expandedStates: recursivelyMapDoc(doc.expandedStates, callback)
19
+ };
20
+ if ("contents" in doc) return {
21
+ ...doc,
22
+ contents: recursivelyMapDoc(doc.contents, callback)
23
+ };
24
+ if ("parts" in doc) return {
25
+ ...doc,
26
+ parts: recursivelyMapDoc(doc.parts, callback)
27
+ };
28
+ if (doc.type === "if-break") return {
29
+ ...doc,
30
+ breakContents: recursivelyMapDoc(doc.breakContents, callback),
31
+ flatContents: recursivelyMapDoc(doc.flatContents, callback)
32
+ };
33
+ const nextDoc = { ...doc };
34
+ for (const [key, value] of Object.entries(nextDoc)) if (value && typeof value === "object") nextDoc[key] = recursivelyMapDoc(value, callback);
35
+ return nextDoc;
36
+ }
37
+ return callback(doc);
38
+ }
39
+ const modifiedHtml = { ...html };
40
+ const htmlPrinter = modifiedHtml.printers?.html;
41
+ if (htmlPrinter?.print) {
42
+ const previousPrint = htmlPrinter.print;
43
+ htmlPrinter.print = (path, options, print, args) => {
44
+ const node = getHtmlNode(path);
45
+ const rawPrintingResult = previousPrint(path, options, print, args);
46
+ if (node?.type === "ieConditionalComment" || node?.kind === "ieConditionalComment") return recursivelyMapDoc(rawPrintingResult, (doc) => {
47
+ if (typeof doc === "object" && doc.type === "line") return doc.soft ? "" : " ";
48
+ return doc;
49
+ });
50
+ return rawPrintingResult;
51
+ };
52
+ }
53
+ const defaults = {
54
+ endOfLine: "lf",
55
+ tabWidth: 2,
56
+ plugins: [modifiedHtml],
57
+ bracketSameLine: true,
58
+ parser: "html"
59
+ };
60
+ const pretty = (str, options = {}) => {
61
+ return format(str.replaceAll("\0", ""), {
62
+ ...defaults,
63
+ ...options
64
+ });
65
+ };
66
+ //#endregion
67
+ //#region src/shared/utils/to-plain-text.ts
68
+ const plainTextSelectors = [
69
+ {
70
+ selector: "img",
71
+ format: "skip"
72
+ },
73
+ {
74
+ selector: "[data-skip-in-text=true]",
75
+ format: "skip"
76
+ },
77
+ {
78
+ selector: "a",
79
+ options: {
80
+ linkBrackets: false,
81
+ hideLinkHrefIfSameAsText: true
82
+ }
83
+ }
84
+ ];
85
+ function toPlainText(html, options) {
86
+ return convert(html, {
87
+ wordwrap: false,
88
+ ...options,
89
+ selectors: [...plainTextSelectors, ...options?.selectors ?? []]
90
+ });
91
+ }
92
+ //#endregion
93
+ //#region src/shared/render.ts
94
+ const doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
95
+ function normalizeRenderable(node) {
96
+ return typeof node === "function" ? node : () => node;
97
+ }
98
+ function decodeSerializedString(value) {
99
+ try {
100
+ const jsonSafe = value.replace(/\\x([0-9A-Fa-f]{2})/g, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
101
+ const parsed = JSON.parse(`"${jsonSafe}"`);
102
+ return typeof parsed === "string" ? parsed : value;
103
+ } catch {
104
+ return value;
105
+ }
106
+ }
107
+ function removeSolidResourceScripts(html) {
108
+ const errorMatch = /Object\.assign\(new Error\("((?:\\.|[^"\\])*)"\)/.exec(html);
109
+ if (errorMatch) throw new Error(decodeSerializedString(errorMatch[1] ?? ""));
110
+ return html.replace(/<script>self\.\$R=self\.\$R\|\|\[\];[\s\S]*?<\/script>/g, "");
111
+ }
112
+ function renderDocument(html) {
113
+ return `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
114
+ }
115
+ function renderSyncOutput(html, options) {
116
+ if (options?.plainText) return toPlainText(html, options.htmlToTextOptions);
117
+ return renderDocument(html);
118
+ }
119
+ async function renderOutput(html, options) {
120
+ if (options?.plainText) return toPlainText(html, options.htmlToTextOptions);
121
+ const document = renderDocument(html);
122
+ if (options?.pretty) return pretty(document);
123
+ return document;
124
+ }
125
+ async function render(node, options) {
126
+ return renderOutput(removeSolidResourceScripts(await renderToStringAsync(normalizeRenderable(node))), options);
127
+ }
128
+ function renderSync(node, options) {
129
+ if (options?.pretty) throw new Error("renderSync does not support pretty output; use render.");
130
+ return renderSyncOutput(removeSolidResourceScripts(renderToString(normalizeRenderable(node))), options);
131
+ }
132
+ //#endregion
133
+ export { plainTextSelectors, pretty, render, renderSync, toPlainText };
134
+
135
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts","../../src/shared/render.ts"],"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 kind?: 'element' | 'text' | 'ieConditionalComment' | 'root';\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 getHtmlNode(path: {\n node?: HtmlNode;\n stack?: Array<Record<string, unknown>>;\n}) {\n const topNode = path.node;\n if (topNode) {\n return topNode;\n }\n\n return path.stack?.[path.stack.length - 1] as unknown as HtmlNode | undefined;\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 === 'line') {\n return callback(doc.soft ? '' : ' ');\n }\n\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 const nextDoc = { ...doc } as Record<string, unknown>;\n for (const [key, value] of Object.entries(nextDoc)) {\n if (value && typeof value === 'object') {\n nextDoc[key] = recursivelyMapDoc(value as builders.Doc, callback);\n }\n }\n\n return nextDoc as unknown as builders.Doc;\n }\n\n return callback(doc);\n}\n\nconst modifiedHtml = { ...html } as Plugin;\nconst htmlPrinter = modifiedHtml.printers?.html;\nif (htmlPrinter?.print) {\n const previousPrint = htmlPrinter.print;\n htmlPrinter.print = (path, options, print, args) => {\n const node = getHtmlNode(path as Parameters<typeof previousPrint>[0]);\n\n const rawPrintingResult = previousPrint(path, options, print, args);\n\n if (\n node?.type === 'ieConditionalComment' ||\n node?.kind === 'ieConditionalComment'\n ) {\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\n// Text-export note: images and\n// preview-only nodes are skipped, and links render without duplicated hrefs.\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 wordwrap: false,\n ...options,\n selectors: [...plainTextSelectors, ...(options?.selectors ?? [])],\n });\n}\n","import type { JSX } from 'solid-js';\nimport {\n renderToString,\n renderToStringAsync,\n} from 'solid-js/web/dist/server.js';\nimport type { Options, RenderSyncOptions } from './options';\nimport { pretty } from './utils/pretty';\nimport { toPlainText } from './utils/to-plain-text';\n\nexport type Renderable = JSX.Element | (() => JSX.Element);\n\nconst doctype =\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">';\n\nfunction normalizeRenderable(node: Renderable) {\n return typeof node === 'function' ? (node as () => JSX.Element) : () => node;\n}\n\nfunction decodeSerializedString(value: string): string {\n try {\n const jsonSafe = value.replace(\n /\\\\x([0-9A-Fa-f]{2})/g,\n (_match, hex: string) => String.fromCharCode(Number.parseInt(hex, 16)),\n );\n const parsed: unknown = JSON.parse(`\"${jsonSafe}\"`);\n return typeof parsed === 'string' ? parsed : value;\n } catch {\n return value;\n }\n}\n\nfunction removeSolidResourceScripts(html: string): string {\n const errorMatch = /Object\\.assign\\(new Error\\(\"((?:\\\\.|[^\"\\\\])*)\"\\)/.exec(\n html,\n );\n if (errorMatch) {\n throw new Error(decodeSerializedString(errorMatch[1] ?? ''));\n }\n return html.replace(\n /<script>self\\.\\$R=self\\.\\$R\\|\\|\\[\\];[\\s\\S]*?<\\/script>/g,\n '',\n );\n}\n\nfunction renderDocument(html: string): string {\n return `${doctype}${html.replace(/<!DOCTYPE.*?>/, '')}`;\n}\n\nfunction renderSyncOutput(html: string, options?: RenderSyncOptions): string {\n if (options?.plainText) {\n return toPlainText(html, options.htmlToTextOptions);\n }\n\n return renderDocument(html);\n}\n\nasync function renderOutput(html: string, options?: Options): Promise<string> {\n if (options?.plainText) {\n return toPlainText(html, options.htmlToTextOptions);\n }\n\n const document = renderDocument(html);\n\n if (options?.pretty) {\n return pretty(document);\n }\n\n return document;\n}\n\n// API note: render accepts either a component function or an already\n// constructed node. Keep that API while rendering through Solid SSR.\nexport async function render(\n node: Renderable,\n options?: Options,\n): Promise<string> {\n const html = removeSolidResourceScripts(\n await renderToStringAsync(normalizeRenderable(node)),\n );\n\n return renderOutput(html, options);\n}\n\nexport function renderSync(\n node: Renderable,\n options?: RenderSyncOptions,\n): string {\n if (options?.pretty) {\n throw new Error('renderSync does not support pretty output; use render.');\n }\n\n const html = removeSolidResourceScripts(\n renderToString(normalizeRenderable(node)),\n );\n\n return renderSyncOutput(html, options);\n}\n"],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let solid_js_web_dist_server_js = require("solid-js/web/dist/server.js");
25
+ let prettier_plugins_html = require("prettier/plugins/html");
26
+ prettier_plugins_html = __toESM(prettier_plugins_html, 1);
27
+ let prettier_standalone = require("prettier/standalone");
28
+ let html_to_text = require("html-to-text");
29
+ //#region src/shared/utils/pretty.ts
30
+ function getHtmlNode(path) {
31
+ const topNode = path.node;
32
+ if (topNode) return topNode;
33
+ return path.stack?.[path.stack.length - 1];
34
+ }
35
+ function recursivelyMapDoc(doc, callback) {
36
+ if (Array.isArray(doc)) return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));
37
+ if (typeof doc === "object") {
38
+ if (doc.type === "line") return callback(doc.soft ? "" : " ");
39
+ if (doc.type === "group") return {
40
+ ...doc,
41
+ contents: recursivelyMapDoc(doc.contents, callback),
42
+ expandedStates: recursivelyMapDoc(doc.expandedStates, callback)
43
+ };
44
+ if ("contents" in doc) return {
45
+ ...doc,
46
+ contents: recursivelyMapDoc(doc.contents, callback)
47
+ };
48
+ if ("parts" in doc) return {
49
+ ...doc,
50
+ parts: recursivelyMapDoc(doc.parts, callback)
51
+ };
52
+ if (doc.type === "if-break") return {
53
+ ...doc,
54
+ breakContents: recursivelyMapDoc(doc.breakContents, callback),
55
+ flatContents: recursivelyMapDoc(doc.flatContents, callback)
56
+ };
57
+ const nextDoc = { ...doc };
58
+ for (const [key, value] of Object.entries(nextDoc)) if (value && typeof value === "object") nextDoc[key] = recursivelyMapDoc(value, callback);
59
+ return nextDoc;
60
+ }
61
+ return callback(doc);
62
+ }
63
+ const modifiedHtml = { ...prettier_plugins_html };
64
+ const htmlPrinter = modifiedHtml.printers?.html;
65
+ if (htmlPrinter?.print) {
66
+ const previousPrint = htmlPrinter.print;
67
+ htmlPrinter.print = (path, options, print, args) => {
68
+ const node = getHtmlNode(path);
69
+ const rawPrintingResult = previousPrint(path, options, print, args);
70
+ if (node?.type === "ieConditionalComment" || node?.kind === "ieConditionalComment") return recursivelyMapDoc(rawPrintingResult, (doc) => {
71
+ if (typeof doc === "object" && doc.type === "line") return doc.soft ? "" : " ";
72
+ return doc;
73
+ });
74
+ return rawPrintingResult;
75
+ };
76
+ }
77
+ const defaults = {
78
+ endOfLine: "lf",
79
+ tabWidth: 2,
80
+ plugins: [modifiedHtml],
81
+ bracketSameLine: true,
82
+ parser: "html"
83
+ };
84
+ const pretty = (str, options = {}) => {
85
+ return (0, prettier_standalone.format)(str.replaceAll("\0", ""), {
86
+ ...defaults,
87
+ ...options
88
+ });
89
+ };
90
+ //#endregion
91
+ //#region src/shared/utils/to-plain-text.ts
92
+ const plainTextSelectors = [
93
+ {
94
+ selector: "img",
95
+ format: "skip"
96
+ },
97
+ {
98
+ selector: "[data-skip-in-text=true]",
99
+ format: "skip"
100
+ },
101
+ {
102
+ selector: "a",
103
+ options: {
104
+ linkBrackets: false,
105
+ hideLinkHrefIfSameAsText: true
106
+ }
107
+ }
108
+ ];
109
+ function toPlainText(html, options) {
110
+ return (0, html_to_text.convert)(html, {
111
+ wordwrap: false,
112
+ ...options,
113
+ selectors: [...plainTextSelectors, ...options?.selectors ?? []]
114
+ });
115
+ }
116
+ //#endregion
117
+ //#region src/shared/render.ts
118
+ const doctype = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
119
+ function normalizeRenderable(node) {
120
+ return typeof node === "function" ? node : () => node;
121
+ }
122
+ function decodeSerializedString(value) {
123
+ try {
124
+ const jsonSafe = value.replace(/\\x([0-9A-Fa-f]{2})/g, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
125
+ const parsed = JSON.parse(`"${jsonSafe}"`);
126
+ return typeof parsed === "string" ? parsed : value;
127
+ } catch {
128
+ return value;
129
+ }
130
+ }
131
+ function removeSolidResourceScripts(html) {
132
+ const errorMatch = /Object\.assign\(new Error\("((?:\\.|[^"\\])*)"\)/.exec(html);
133
+ if (errorMatch) throw new Error(decodeSerializedString(errorMatch[1] ?? ""));
134
+ return html.replace(/<script>self\.\$R=self\.\$R\|\|\[\];[\s\S]*?<\/script>/g, "");
135
+ }
136
+ function renderDocument(html) {
137
+ return `${doctype}${html.replace(/<!DOCTYPE.*?>/, "")}`;
138
+ }
139
+ function renderSyncOutput(html, options) {
140
+ if (options?.plainText) return toPlainText(html, options.htmlToTextOptions);
141
+ return renderDocument(html);
142
+ }
143
+ async function renderOutput(html, options) {
144
+ if (options?.plainText) return toPlainText(html, options.htmlToTextOptions);
145
+ const document = renderDocument(html);
146
+ if (options?.pretty) return pretty(document);
147
+ return document;
148
+ }
149
+ async function render(node, options) {
150
+ return renderOutput(removeSolidResourceScripts(await (0, solid_js_web_dist_server_js.renderToStringAsync)(normalizeRenderable(node))), options);
151
+ }
152
+ function renderSync(node, options) {
153
+ if (options?.pretty) throw new Error("renderSync does not support pretty output; use render.");
154
+ return renderSyncOutput(removeSolidResourceScripts((0, solid_js_web_dist_server_js.renderToString)(normalizeRenderable(node))), options);
155
+ }
156
+ //#endregion
157
+ exports.plainTextSelectors = plainTextSelectors;
158
+ exports.pretty = pretty;
159
+ exports.render = render;
160
+ exports.renderSync = renderSync;
161
+ exports.toPlainText = toPlainText;
@@ -0,0 +1,34 @@
1
+ import { HtmlToTextOptions, SelectorDefinition } from "html-to-text";
2
+ import { JSX } from "solid-js";
3
+ import { Options as Options$1 } from "prettier";
4
+
5
+ //#region src/shared/options.d.ts
6
+ type PlainTextDisabled = {
7
+ plainText?: false;
8
+ };
9
+ type PlainTextEnabled = {
10
+ plainText?: true;
11
+ htmlToTextOptions?: HtmlToTextOptions;
12
+ };
13
+ type PlainTextOptions = PlainTextDisabled | PlainTextEnabled;
14
+ type Options = {
15
+ pretty?: boolean;
16
+ } & PlainTextOptions;
17
+ type RenderSyncOptions = {
18
+ pretty?: false;
19
+ } & PlainTextOptions;
20
+ //#endregion
21
+ //#region src/shared/render.d.ts
22
+ type Renderable = JSX.Element | (() => JSX.Element);
23
+ declare function render(node: Renderable, options?: Options): Promise<string>;
24
+ declare function renderSync(node: Renderable, options?: RenderSyncOptions): string;
25
+ //#endregion
26
+ //#region src/shared/utils/pretty.d.ts
27
+ declare const pretty: (str: string, options?: Options$1) => Promise<string>;
28
+ //#endregion
29
+ //#region src/shared/utils/to-plain-text.d.ts
30
+ declare const plainTextSelectors: SelectorDefinition[];
31
+ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
32
+ //#endregion
33
+ export { Options, RenderSyncOptions, Renderable, plainTextSelectors, pretty, render, renderSync, toPlainText };
34
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/render.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts"],"mappings":";;;;;KAEK,iBAAA;EACH,SAAS;AAAA;AAAA,KAGN,gBAAA;EACH,SAAA;EACA,iBAAA,GAAoB,iBAAiB;AAAA;AAAA,KAGlC,gBAAA,GAAmB,iBAAA,GAAoB,gBAAgB;AAAA,KAEhD,OAAA;EACV,MAAA;AAAA,IACE,gBAAgB;AAAA,KAER,iBAAA;EACV,MAAA;AAAA,IACE,gBAAgB;;;KCVR,UAAA,GAAa,GAAA,CAAI,OAAA,UAAiB,GAAA,CAAI,OAAO;AAAA,iBA+DnC,MAAA,CACpB,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,OAAA,GACT,OAAA;AAAA,iBAQa,UAAA,CACd,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,iBAAiB;;;cCuChB,MAAA,GAAU,GAAA,UAAa,OAAA,GAAS,SAAA,KAAY,OAAA;;;cCpH5C,kBAAA,EAAoB,kBAAkB;AAAA,iBASnC,WAAA,CAAY,IAAA,UAAc,OAAA,GAAU,iBAAiB"}
@@ -0,0 +1,34 @@
1
+ import { HtmlToTextOptions, SelectorDefinition } from "html-to-text";
2
+ import { JSX } from "solid-js";
3
+ import { Options as Options$1 } from "prettier";
4
+
5
+ //#region src/shared/options.d.ts
6
+ type PlainTextDisabled = {
7
+ plainText?: false;
8
+ };
9
+ type PlainTextEnabled = {
10
+ plainText?: true;
11
+ htmlToTextOptions?: HtmlToTextOptions;
12
+ };
13
+ type PlainTextOptions = PlainTextDisabled | PlainTextEnabled;
14
+ type Options = {
15
+ pretty?: boolean;
16
+ } & PlainTextOptions;
17
+ type RenderSyncOptions = {
18
+ pretty?: false;
19
+ } & PlainTextOptions;
20
+ //#endregion
21
+ //#region src/shared/render.d.ts
22
+ type Renderable = JSX.Element | (() => JSX.Element);
23
+ declare function render(node: Renderable, options?: Options): Promise<string>;
24
+ declare function renderSync(node: Renderable, options?: RenderSyncOptions): string;
25
+ //#endregion
26
+ //#region src/shared/utils/pretty.d.ts
27
+ declare const pretty: (str: string, options?: Options$1) => Promise<string>;
28
+ //#endregion
29
+ //#region src/shared/utils/to-plain-text.d.ts
30
+ declare const plainTextSelectors: SelectorDefinition[];
31
+ declare function toPlainText(html: string, options?: HtmlToTextOptions): string;
32
+ //#endregion
33
+ export { Options, RenderSyncOptions, Renderable, plainTextSelectors, pretty, render, renderSync, toPlainText };
34
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/shared/options.ts","../../src/shared/render.ts","../../src/shared/utils/pretty.ts","../../src/shared/utils/to-plain-text.ts"],"mappings":";;;;;KAEK,iBAAA;EACH,SAAS;AAAA;AAAA,KAGN,gBAAA;EACH,SAAA;EACA,iBAAA,GAAoB,iBAAiB;AAAA;AAAA,KAGlC,gBAAA,GAAmB,iBAAA,GAAoB,gBAAgB;AAAA,KAEhD,OAAA;EACV,MAAA;AAAA,IACE,gBAAgB;AAAA,KAER,iBAAA;EACV,MAAA;AAAA,IACE,gBAAgB;;;KCVR,UAAA,GAAa,GAAA,CAAI,OAAA,UAAiB,GAAA,CAAI,OAAO;AAAA,iBA+DnC,MAAA,CACpB,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,OAAA,GACT,OAAA;AAAA,iBAQa,UAAA,CACd,IAAA,EAAM,UAAA,EACN,OAAA,GAAU,iBAAiB;;;cCuChB,MAAA,GAAU,GAAA,UAAa,OAAA,GAAS,SAAA,KAAY,OAAA;;;cCpH5C,kBAAA,EAAoB,kBAAkB;AAAA,iBASnC,WAAA,CAAY,IAAA,UAAc,OAAA,GAAU,iBAAiB"}