@pyreon/document 0.0.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/LICENSE +21 -0
- package/lib/analysis/index.js.html +5406 -0
- package/lib/chunk-ErZ26oRB.js +48 -0
- package/lib/confluence-Va8e7RxQ.js +192 -0
- package/lib/confluence-Va8e7RxQ.js.map +1 -0
- package/lib/csv-2c38ub-Y.js +32 -0
- package/lib/csv-2c38ub-Y.js.map +1 -0
- package/lib/discord-DAoUZqvE.js +134 -0
- package/lib/discord-DAoUZqvE.js.map +1 -0
- package/lib/dist-BsqdI2nY.js +20179 -0
- package/lib/dist-BsqdI2nY.js.map +1 -0
- package/lib/docx-CorFwEH9.js +450 -0
- package/lib/docx-CorFwEH9.js.map +1 -0
- package/lib/email-Bn_Brjdp.js +131 -0
- package/lib/email-Bn_Brjdp.js.map +1 -0
- package/lib/exceljs-BoIDUUaw.js +34377 -0
- package/lib/exceljs-BoIDUUaw.js.map +1 -0
- package/lib/google-chat-B6I017I1.js +125 -0
- package/lib/google-chat-B6I017I1.js.map +1 -0
- package/lib/html-De_iS_f0.js +151 -0
- package/lib/html-De_iS_f0.js.map +1 -0
- package/lib/index.js +619 -0
- package/lib/index.js.map +1 -0
- package/lib/markdown-BYC_3C9i.js +75 -0
- package/lib/markdown-BYC_3C9i.js.map +1 -0
- package/lib/notion-DHaQHO6P.js +187 -0
- package/lib/notion-DHaQHO6P.js.map +1 -0
- package/lib/pdf-CDPc5Itc.js +419 -0
- package/lib/pdf-CDPc5Itc.js.map +1 -0
- package/lib/pdfmake-DnmLxK4Q.js +55511 -0
- package/lib/pdfmake-DnmLxK4Q.js.map +1 -0
- package/lib/pptx-DKQU6bjq.js +252 -0
- package/lib/pptx-DKQU6bjq.js.map +1 -0
- package/lib/pptxgen.es-COcgXsyx.js +5697 -0
- package/lib/pptxgen.es-COcgXsyx.js.map +1 -0
- package/lib/slack-CJRJgkag.js +139 -0
- package/lib/slack-CJRJgkag.js.map +1 -0
- package/lib/svg-BM8biZmL.js +187 -0
- package/lib/svg-BM8biZmL.js.map +1 -0
- package/lib/teams-S99tonRG.js +176 -0
- package/lib/teams-S99tonRG.js.map +1 -0
- package/lib/telegram-CbEO_2PN.js +77 -0
- package/lib/telegram-CbEO_2PN.js.map +1 -0
- package/lib/text-B5U8ucRr.js +75 -0
- package/lib/text-B5U8ucRr.js.map +1 -0
- package/lib/types/index.d.ts +528 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/vfs_fonts-Df1kkZ4Y.js +19 -0
- package/lib/vfs_fonts-Df1kkZ4Y.js.map +1 -0
- package/lib/whatsapp-DJ2D1jGG.js +64 -0
- package/lib/whatsapp-DJ2D1jGG.js.map +1 -0
- package/lib/xlsx-D47x-gZ5.js +199 -0
- package/lib/xlsx-D47x-gZ5.js.map +1 -0
- package/package.json +62 -0
- package/src/builder.ts +266 -0
- package/src/download.ts +76 -0
- package/src/env.d.ts +17 -0
- package/src/index.ts +98 -0
- package/src/nodes.ts +315 -0
- package/src/render.ts +222 -0
- package/src/renderers/confluence.ts +231 -0
- package/src/renderers/csv.ts +67 -0
- package/src/renderers/discord.ts +192 -0
- package/src/renderers/docx.ts +612 -0
- package/src/renderers/email.ts +230 -0
- package/src/renderers/google-chat.ts +211 -0
- package/src/renderers/html.ts +225 -0
- package/src/renderers/markdown.ts +144 -0
- package/src/renderers/notion.ts +264 -0
- package/src/renderers/pdf.ts +427 -0
- package/src/renderers/pptx.ts +353 -0
- package/src/renderers/slack.ts +192 -0
- package/src/renderers/svg.ts +254 -0
- package/src/renderers/teams.ts +234 -0
- package/src/renderers/telegram.ts +137 -0
- package/src/renderers/text.ts +154 -0
- package/src/renderers/whatsapp.ts +121 -0
- package/src/renderers/xlsx.ts +342 -0
- package/src/tests/document.test.ts +2920 -0
- package/src/types.ts +291 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
9
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
10
|
+
var __exportAll = (all, no_symbols) => {
|
|
11
|
+
let target = {};
|
|
12
|
+
for (var name in all) {
|
|
13
|
+
__defProp(target, name, {
|
|
14
|
+
get: all[name],
|
|
15
|
+
enumerable: true
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
if (!no_symbols) {
|
|
19
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
20
|
+
}
|
|
21
|
+
return target;
|
|
22
|
+
};
|
|
23
|
+
var __copyProps = (to, from, except, desc) => {
|
|
24
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
26
|
+
key = keys[i];
|
|
27
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
28
|
+
__defProp(to, key, {
|
|
29
|
+
get: ((k) => from[k]).bind(null, key),
|
|
30
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return to;
|
|
36
|
+
};
|
|
37
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
38
|
+
value: mod,
|
|
39
|
+
enumerable: true
|
|
40
|
+
}) : target, mod));
|
|
41
|
+
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
42
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
43
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
44
|
+
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { __toCommonJS as a, __require as i, __esmMin as n, __toESM as o, __exportAll as r, __commonJSMin as t };
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
//#region src/renderers/confluence.ts
|
|
2
|
+
/**
|
|
3
|
+
* Atlassian Document Format (ADF) renderer — for Jira and Confluence.
|
|
4
|
+
* ADF is the JSON format used by Atlassian's Document API.
|
|
5
|
+
* Can be posted to Confluence pages, Jira issue descriptions, and comments.
|
|
6
|
+
*/
|
|
7
|
+
function resolveColumn(col) {
|
|
8
|
+
return typeof col === "string" ? { header: col } : col;
|
|
9
|
+
}
|
|
10
|
+
function getTextContent(children) {
|
|
11
|
+
return children.map((c) => typeof c === "string" ? c : getTextContent(c.children)).join("");
|
|
12
|
+
}
|
|
13
|
+
function textNode(text, marks) {
|
|
14
|
+
return {
|
|
15
|
+
type: "text",
|
|
16
|
+
text,
|
|
17
|
+
...marks && marks.length > 0 ? { marks } : {}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function nodeToAdf(node) {
|
|
21
|
+
const p = node.props;
|
|
22
|
+
const result = [];
|
|
23
|
+
switch (node.type) {
|
|
24
|
+
case "document":
|
|
25
|
+
case "page":
|
|
26
|
+
case "section":
|
|
27
|
+
case "row":
|
|
28
|
+
case "column":
|
|
29
|
+
for (const child of node.children) if (typeof child !== "string") result.push(...nodeToAdf(child));
|
|
30
|
+
break;
|
|
31
|
+
case "heading": {
|
|
32
|
+
const level = Math.min(Math.max(p.level ?? 1, 1), 6);
|
|
33
|
+
const text = getTextContent(node.children);
|
|
34
|
+
result.push({
|
|
35
|
+
type: "heading",
|
|
36
|
+
attrs: { level },
|
|
37
|
+
content: [textNode(text, [{ type: "strong" }])]
|
|
38
|
+
});
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case "text": {
|
|
42
|
+
const text = getTextContent(node.children);
|
|
43
|
+
const marks = [];
|
|
44
|
+
if (p.bold) marks.push({ type: "strong" });
|
|
45
|
+
if (p.italic) marks.push({ type: "em" });
|
|
46
|
+
if (p.underline) marks.push({ type: "underline" });
|
|
47
|
+
if (p.strikethrough) marks.push({ type: "strike" });
|
|
48
|
+
if (p.color) marks.push({
|
|
49
|
+
type: "textColor",
|
|
50
|
+
attrs: { color: p.color }
|
|
51
|
+
});
|
|
52
|
+
result.push({
|
|
53
|
+
type: "paragraph",
|
|
54
|
+
content: [textNode(text, marks)]
|
|
55
|
+
});
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
case "link": {
|
|
59
|
+
const href = p.href;
|
|
60
|
+
const text = getTextContent(node.children);
|
|
61
|
+
result.push({
|
|
62
|
+
type: "paragraph",
|
|
63
|
+
content: [textNode(text, [{
|
|
64
|
+
type: "link",
|
|
65
|
+
attrs: { href }
|
|
66
|
+
}])]
|
|
67
|
+
});
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "image": {
|
|
71
|
+
const src = p.src;
|
|
72
|
+
if (src.startsWith("http")) result.push({
|
|
73
|
+
type: "mediaSingle",
|
|
74
|
+
attrs: { layout: "center" },
|
|
75
|
+
content: [{
|
|
76
|
+
type: "media",
|
|
77
|
+
attrs: {
|
|
78
|
+
type: "external",
|
|
79
|
+
url: src,
|
|
80
|
+
width: p.width ?? void 0,
|
|
81
|
+
height: p.height ?? void 0
|
|
82
|
+
}
|
|
83
|
+
}]
|
|
84
|
+
});
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case "table": {
|
|
88
|
+
const columns = (p.columns ?? []).map(resolveColumn);
|
|
89
|
+
const rows = p.rows ?? [];
|
|
90
|
+
const headerRow = {
|
|
91
|
+
type: "tableRow",
|
|
92
|
+
content: columns.map((col) => ({
|
|
93
|
+
type: "tableHeader",
|
|
94
|
+
content: [{
|
|
95
|
+
type: "paragraph",
|
|
96
|
+
content: [textNode(col.header, [{ type: "strong" }])]
|
|
97
|
+
}]
|
|
98
|
+
}))
|
|
99
|
+
};
|
|
100
|
+
const dataRows = rows.map((row) => ({
|
|
101
|
+
type: "tableRow",
|
|
102
|
+
content: columns.map((_, i) => ({
|
|
103
|
+
type: "tableCell",
|
|
104
|
+
content: [{
|
|
105
|
+
type: "paragraph",
|
|
106
|
+
content: [textNode(String(row[i] ?? ""))]
|
|
107
|
+
}]
|
|
108
|
+
}))
|
|
109
|
+
}));
|
|
110
|
+
result.push({
|
|
111
|
+
type: "table",
|
|
112
|
+
attrs: {
|
|
113
|
+
isNumberColumnEnabled: false,
|
|
114
|
+
layout: "default"
|
|
115
|
+
},
|
|
116
|
+
content: [headerRow, ...dataRows]
|
|
117
|
+
});
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case "list": {
|
|
121
|
+
const type = p.ordered ? "orderedList" : "bulletList";
|
|
122
|
+
const items = node.children.filter((c) => typeof c !== "string").map((item) => ({
|
|
123
|
+
type: "listItem",
|
|
124
|
+
content: [{
|
|
125
|
+
type: "paragraph",
|
|
126
|
+
content: [textNode(getTextContent(item.children))]
|
|
127
|
+
}]
|
|
128
|
+
}));
|
|
129
|
+
result.push({
|
|
130
|
+
type,
|
|
131
|
+
content: items
|
|
132
|
+
});
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "code": {
|
|
136
|
+
const text = getTextContent(node.children);
|
|
137
|
+
const lang = p.language ?? null;
|
|
138
|
+
result.push({
|
|
139
|
+
type: "codeBlock",
|
|
140
|
+
attrs: { language: lang },
|
|
141
|
+
content: [textNode(text)]
|
|
142
|
+
});
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case "divider":
|
|
146
|
+
case "page-break":
|
|
147
|
+
result.push({ type: "rule" });
|
|
148
|
+
break;
|
|
149
|
+
case "spacer":
|
|
150
|
+
result.push({
|
|
151
|
+
type: "paragraph",
|
|
152
|
+
content: []
|
|
153
|
+
});
|
|
154
|
+
break;
|
|
155
|
+
case "button": {
|
|
156
|
+
const href = p.href;
|
|
157
|
+
const text = getTextContent(node.children);
|
|
158
|
+
result.push({
|
|
159
|
+
type: "paragraph",
|
|
160
|
+
content: [textNode(text, [{
|
|
161
|
+
type: "link",
|
|
162
|
+
attrs: { href }
|
|
163
|
+
}, { type: "strong" }])]
|
|
164
|
+
});
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case "quote": {
|
|
168
|
+
const text = getTextContent(node.children);
|
|
169
|
+
result.push({
|
|
170
|
+
type: "blockquote",
|
|
171
|
+
content: [{
|
|
172
|
+
type: "paragraph",
|
|
173
|
+
content: [textNode(text)]
|
|
174
|
+
}]
|
|
175
|
+
});
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
const confluenceRenderer = { async render(node, _options) {
|
|
182
|
+
const adf = {
|
|
183
|
+
version: 1,
|
|
184
|
+
type: "doc",
|
|
185
|
+
content: nodeToAdf(node)
|
|
186
|
+
};
|
|
187
|
+
return JSON.stringify(adf, null, 2);
|
|
188
|
+
} };
|
|
189
|
+
|
|
190
|
+
//#endregion
|
|
191
|
+
export { confluenceRenderer };
|
|
192
|
+
//# sourceMappingURL=confluence-Va8e7RxQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence-Va8e7RxQ.js","names":[],"sources":["../src/renderers/confluence.ts"],"sourcesContent":["import type {\n DocChild,\n DocNode,\n DocumentRenderer,\n RenderOptions,\n TableColumn,\n} from '../types'\n\n/**\n * Atlassian Document Format (ADF) renderer — for Jira and Confluence.\n * ADF is the JSON format used by Atlassian's Document API.\n * Can be posted to Confluence pages, Jira issue descriptions, and comments.\n */\n\nfunction resolveColumn(col: string | TableColumn): TableColumn {\n return typeof col === 'string' ? { header: col } : col\n}\n\nfunction getTextContent(children: DocChild[]): string {\n return children\n .map((c) =>\n typeof c === 'string' ? c : getTextContent((c as DocNode).children),\n )\n .join('')\n}\n\ninterface AdfNode {\n type: string\n content?: AdfNode[]\n text?: string\n marks?: { type: string; attrs?: Record<string, unknown> }[]\n attrs?: Record<string, unknown>\n}\n\nfunction textNode(text: string, marks?: AdfNode['marks']): AdfNode {\n return { type: 'text', text, ...(marks && marks.length > 0 ? { marks } : {}) }\n}\n\nfunction nodeToAdf(node: DocNode): AdfNode[] {\n const p = node.props\n const result: AdfNode[] = []\n\n switch (node.type) {\n case 'document':\n case 'page':\n case 'section':\n case 'row':\n case 'column':\n for (const child of node.children) {\n if (typeof child !== 'string') {\n result.push(...nodeToAdf(child))\n }\n }\n break\n\n case 'heading': {\n const level = Math.min(Math.max((p.level as number) ?? 1, 1), 6)\n const text = getTextContent(node.children)\n result.push({\n type: 'heading',\n attrs: { level },\n content: [textNode(text, [{ type: 'strong' }])],\n })\n break\n }\n\n case 'text': {\n const text = getTextContent(node.children)\n const marks: AdfNode['marks'] = []\n if (p.bold) marks.push({ type: 'strong' })\n if (p.italic) marks.push({ type: 'em' })\n if (p.underline) marks.push({ type: 'underline' })\n if (p.strikethrough) marks.push({ type: 'strike' })\n if (p.color)\n marks.push({ type: 'textColor', attrs: { color: p.color as string } })\n result.push({\n type: 'paragraph',\n content: [textNode(text, marks)],\n })\n break\n }\n\n case 'link': {\n const href = p.href as string\n const text = getTextContent(node.children)\n result.push({\n type: 'paragraph',\n content: [textNode(text, [{ type: 'link', attrs: { href } }])],\n })\n break\n }\n\n case 'image': {\n const src = p.src as string\n if (src.startsWith('http')) {\n result.push({\n type: 'mediaSingle',\n attrs: { layout: 'center' },\n content: [\n {\n type: 'media',\n attrs: {\n type: 'external',\n url: src,\n width: (p.width as number) ?? undefined,\n height: (p.height as number) ?? undefined,\n },\n },\n ],\n })\n }\n break\n }\n\n case 'table': {\n const columns = ((p.columns ?? []) as (string | TableColumn)[]).map(\n resolveColumn,\n )\n const rows = (p.rows ?? []) as (string | number)[][]\n\n const headerRow: AdfNode = {\n type: 'tableRow',\n content: columns.map((col) => ({\n type: 'tableHeader',\n content: [\n {\n type: 'paragraph',\n content: [textNode(col.header, [{ type: 'strong' }])],\n },\n ],\n })),\n }\n\n const dataRows = rows.map((row) => ({\n type: 'tableRow' as const,\n content: columns.map((_, i) => ({\n type: 'tableCell' as const,\n content: [\n {\n type: 'paragraph' as const,\n content: [textNode(String(row[i] ?? ''))],\n },\n ],\n })),\n }))\n\n result.push({\n type: 'table',\n attrs: { isNumberColumnEnabled: false, layout: 'default' },\n content: [headerRow, ...dataRows],\n })\n break\n }\n\n case 'list': {\n const ordered = p.ordered as boolean | undefined\n const type = ordered ? 'orderedList' : 'bulletList'\n const items = node.children\n .filter((c): c is DocNode => typeof c !== 'string')\n .map((item) => ({\n type: 'listItem' as const,\n content: [\n {\n type: 'paragraph' as const,\n content: [textNode(getTextContent(item.children))],\n },\n ],\n }))\n result.push({ type, content: items })\n break\n }\n\n case 'code': {\n const text = getTextContent(node.children)\n const lang = (p.language as string) ?? null\n result.push({\n type: 'codeBlock',\n attrs: { language: lang },\n content: [textNode(text)],\n })\n break\n }\n\n case 'divider':\n case 'page-break':\n result.push({ type: 'rule' })\n break\n\n case 'spacer':\n result.push({ type: 'paragraph', content: [] })\n break\n\n case 'button': {\n const href = p.href as string\n const text = getTextContent(node.children)\n result.push({\n type: 'paragraph',\n content: [\n textNode(text, [\n { type: 'link', attrs: { href } },\n { type: 'strong' },\n ]),\n ],\n })\n break\n }\n\n case 'quote': {\n const text = getTextContent(node.children)\n result.push({\n type: 'blockquote',\n content: [{ type: 'paragraph', content: [textNode(text)] }],\n })\n break\n }\n }\n\n return result\n}\n\nexport const confluenceRenderer: DocumentRenderer = {\n async render(node: DocNode, _options?: RenderOptions): Promise<string> {\n const content = nodeToAdf(node)\n const adf = {\n version: 1,\n type: 'doc',\n content,\n }\n return JSON.stringify(adf, null, 2)\n },\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/renderers/csv.ts
|
|
2
|
+
function resolveColumn(col) {
|
|
3
|
+
return typeof col === "string" ? { header: col } : col;
|
|
4
|
+
}
|
|
5
|
+
function escapeCsv(value) {
|
|
6
|
+
if (value.includes(",") || value.includes("\"") || value.includes("\n")) return `"${value.replace(/"/g, "\"\"")}"`;
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
function findTables(node) {
|
|
10
|
+
const tables = [];
|
|
11
|
+
if (node.type === "table") tables.push(node);
|
|
12
|
+
for (const child of node.children) if (typeof child !== "string") tables.push(...findTables(child));
|
|
13
|
+
return tables;
|
|
14
|
+
}
|
|
15
|
+
function tableToCsv(node) {
|
|
16
|
+
const columns = (node.props.columns ?? []).map(resolveColumn);
|
|
17
|
+
const rows = node.props.rows ?? [];
|
|
18
|
+
const lines = [];
|
|
19
|
+
if (node.props.caption) lines.push(`# ${node.props.caption}`);
|
|
20
|
+
lines.push(columns.map((c) => escapeCsv(c.header)).join(","));
|
|
21
|
+
for (const row of rows) lines.push(row.map((cell) => escapeCsv(String(cell ?? ""))).join(","));
|
|
22
|
+
return lines.join("\n");
|
|
23
|
+
}
|
|
24
|
+
const csvRenderer = { async render(node, _options) {
|
|
25
|
+
const tables = findTables(node);
|
|
26
|
+
if (tables.length === 0) return "# No tables found in document\n";
|
|
27
|
+
return `${tables.map(tableToCsv).join("\n\n")}\n`;
|
|
28
|
+
} };
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { csvRenderer };
|
|
32
|
+
//# sourceMappingURL=csv-2c38ub-Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-2c38ub-Y.js","names":[],"sources":["../src/renderers/csv.ts"],"sourcesContent":["import type {\n DocNode,\n DocumentRenderer,\n RenderOptions,\n TableColumn,\n} from '../types'\n\nfunction resolveColumn(col: string | TableColumn): TableColumn {\n return typeof col === 'string' ? { header: col } : col\n}\n\nfunction escapeCsv(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`\n }\n return value\n}\n\nfunction findTables(node: DocNode): DocNode[] {\n const tables: DocNode[] = []\n if (node.type === 'table') {\n tables.push(node)\n }\n for (const child of node.children) {\n if (typeof child !== 'string') {\n tables.push(...findTables(child))\n }\n }\n return tables\n}\n\nfunction tableToCsv(node: DocNode): string {\n const columns = ((node.props.columns ?? []) as (string | TableColumn)[]).map(\n resolveColumn,\n )\n const rows = (node.props.rows ?? []) as (string | number)[][]\n\n const lines: string[] = []\n\n // Caption as comment\n if (node.props.caption) {\n lines.push(`# ${node.props.caption}`)\n }\n\n // Header\n lines.push(columns.map((c) => escapeCsv(c.header)).join(','))\n\n // Rows\n for (const row of rows) {\n lines.push(row.map((cell) => escapeCsv(String(cell ?? ''))).join(','))\n }\n\n return lines.join('\\n')\n}\n\nexport const csvRenderer: DocumentRenderer = {\n async render(node: DocNode, _options?: RenderOptions): Promise<string> {\n const tables = findTables(node)\n\n if (tables.length === 0) {\n return '# No tables found in document\\n'\n }\n\n // If multiple tables, separate with blank lines\n return `${tables.map(tableToCsv).join('\\n\\n')}\\n`\n },\n}\n"],"mappings":";AAOA,SAAS,cAAc,KAAwC;AAC7D,QAAO,OAAO,QAAQ,WAAW,EAAE,QAAQ,KAAK,GAAG;;AAGrD,SAAS,UAAU,OAAuB;AACxC,KAAI,MAAM,SAAS,IAAI,IAAI,MAAM,SAAS,KAAI,IAAI,MAAM,SAAS,KAAK,CACpE,QAAO,IAAI,MAAM,QAAQ,MAAM,OAAK,CAAC;AAEvC,QAAO;;AAGT,SAAS,WAAW,MAA0B;CAC5C,MAAM,SAAoB,EAAE;AAC5B,KAAI,KAAK,SAAS,QAChB,QAAO,KAAK,KAAK;AAEnB,MAAK,MAAM,SAAS,KAAK,SACvB,KAAI,OAAO,UAAU,SACnB,QAAO,KAAK,GAAG,WAAW,MAAM,CAAC;AAGrC,QAAO;;AAGT,SAAS,WAAW,MAAuB;CACzC,MAAM,WAAY,KAAK,MAAM,WAAW,EAAE,EAA+B,IACvE,cACD;CACD,MAAM,OAAQ,KAAK,MAAM,QAAQ,EAAE;CAEnC,MAAM,QAAkB,EAAE;AAG1B,KAAI,KAAK,MAAM,QACb,OAAM,KAAK,KAAK,KAAK,MAAM,UAAU;AAIvC,OAAM,KAAK,QAAQ,KAAK,MAAM,UAAU,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC;AAG7D,MAAK,MAAM,OAAO,KAChB,OAAM,KAAK,IAAI,KAAK,SAAS,UAAU,OAAO,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAGxE,QAAO,MAAM,KAAK,KAAK;;AAGzB,MAAa,cAAgC,EAC3C,MAAM,OAAO,MAAe,UAA2C;CACrE,MAAM,SAAS,WAAW,KAAK;AAE/B,KAAI,OAAO,WAAW,EACpB,QAAO;AAIT,QAAO,GAAG,OAAO,IAAI,WAAW,CAAC,KAAK,OAAO,CAAC;GAEjD"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
//#region src/renderers/discord.ts
|
|
2
|
+
/**
|
|
3
|
+
* Discord renderer — outputs embed JSON for Discord webhooks/bots.
|
|
4
|
+
* Uses Discord's markdown subset and embed structure.
|
|
5
|
+
*/
|
|
6
|
+
function resolveColumn(col) {
|
|
7
|
+
return typeof col === "string" ? { header: col } : col;
|
|
8
|
+
}
|
|
9
|
+
function getTextContent(children) {
|
|
10
|
+
return children.map((c) => typeof c === "string" ? c : getTextContent(c.children)).join("");
|
|
11
|
+
}
|
|
12
|
+
/** Extract the first h1 title and first HTTP image from the tree. */
|
|
13
|
+
function extractMeta(node) {
|
|
14
|
+
if (node.type === "heading") {
|
|
15
|
+
if ((node.props.level ?? 1) === 1) return { title: getTextContent(node.children) };
|
|
16
|
+
}
|
|
17
|
+
if (node.type === "image") {
|
|
18
|
+
const src = node.props.src;
|
|
19
|
+
if (src.startsWith("http")) return { imageUrl: src };
|
|
20
|
+
}
|
|
21
|
+
for (const child of node.children) if (typeof child !== "string") {
|
|
22
|
+
const result = extractMeta(child);
|
|
23
|
+
if (result.title || result.imageUrl) return result;
|
|
24
|
+
}
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
function nodeToMarkdown(node, meta) {
|
|
28
|
+
const p = node.props;
|
|
29
|
+
let content = "";
|
|
30
|
+
const fields = [];
|
|
31
|
+
switch (node.type) {
|
|
32
|
+
case "document":
|
|
33
|
+
case "page":
|
|
34
|
+
case "section":
|
|
35
|
+
case "row":
|
|
36
|
+
case "column":
|
|
37
|
+
for (const child of node.children) if (typeof child !== "string") {
|
|
38
|
+
const result = nodeToMarkdown(child, meta);
|
|
39
|
+
content += result.content;
|
|
40
|
+
fields.push(...result.fields);
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
case "heading": {
|
|
44
|
+
const text = getTextContent(node.children);
|
|
45
|
+
if ((p.level ?? 1) === 1 && text === meta.title) break;
|
|
46
|
+
content += `**${text}**\n\n`;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case "text": {
|
|
50
|
+
let text = getTextContent(node.children);
|
|
51
|
+
if (p.bold) text = `**${text}**`;
|
|
52
|
+
if (p.italic) text = `*${text}*`;
|
|
53
|
+
if (p.strikethrough) text = `~~${text}~~`;
|
|
54
|
+
content += `${text}\n\n`;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case "link": {
|
|
58
|
+
const href = p.href;
|
|
59
|
+
const text = getTextContent(node.children);
|
|
60
|
+
content += `[${text}](${href})\n\n`;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case "image": break;
|
|
64
|
+
case "table": {
|
|
65
|
+
const columns = (p.columns ?? []).map(resolveColumn);
|
|
66
|
+
const rows = p.rows ?? [];
|
|
67
|
+
if (columns.length <= 3 && rows.length <= 10) for (const col of columns) {
|
|
68
|
+
const colIdx = columns.indexOf(col);
|
|
69
|
+
const values = rows.map((row) => String(row[colIdx] ?? "")).join("\n");
|
|
70
|
+
fields.push({
|
|
71
|
+
name: col.header,
|
|
72
|
+
value: values || "-",
|
|
73
|
+
inline: true
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const header = columns.map((c) => c.header).join(" | ");
|
|
78
|
+
const separator = columns.map(() => "---").join(" | ");
|
|
79
|
+
const body = rows.map((row) => row.map((c) => String(c ?? "")).join(" | ")).join("\n");
|
|
80
|
+
content += `\`\`\`\n${header}\n${separator}\n${body}\n\`\`\`\n\n`;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case "list": {
|
|
85
|
+
const ordered = p.ordered;
|
|
86
|
+
const items = node.children.filter((c) => typeof c !== "string").map((item, i) => {
|
|
87
|
+
return `${ordered ? `${i + 1}.` : "•"} ${getTextContent(item.children)}`;
|
|
88
|
+
}).join("\n");
|
|
89
|
+
content += `${items}\n\n`;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "code": {
|
|
93
|
+
const lang = p.language ?? "";
|
|
94
|
+
const text = getTextContent(node.children);
|
|
95
|
+
content += `\`\`\`${lang}\n${text}\n\`\`\`\n\n`;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case "divider":
|
|
99
|
+
case "page-break":
|
|
100
|
+
content += "───────────\n\n";
|
|
101
|
+
break;
|
|
102
|
+
case "button": {
|
|
103
|
+
const href = p.href;
|
|
104
|
+
const text = getTextContent(node.children);
|
|
105
|
+
content += `[**${text}**](${href})\n\n`;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "quote": {
|
|
109
|
+
const text = getTextContent(node.children);
|
|
110
|
+
content += `> ${text}\n\n`;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
content,
|
|
116
|
+
fields
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const discordRenderer = { async render(node, _options) {
|
|
120
|
+
const meta = extractMeta(node);
|
|
121
|
+
const { content, fields } = nodeToMarkdown(node, meta);
|
|
122
|
+
const embed = {
|
|
123
|
+
title: meta.title ?? node.props.title ?? void 0,
|
|
124
|
+
description: content.trim() || void 0,
|
|
125
|
+
color: 5195493
|
|
126
|
+
};
|
|
127
|
+
if (fields.length > 0) embed.fields = fields;
|
|
128
|
+
if (meta.imageUrl) embed.image = { url: meta.imageUrl };
|
|
129
|
+
return JSON.stringify({ embeds: [embed] }, null, 2);
|
|
130
|
+
} };
|
|
131
|
+
|
|
132
|
+
//#endregion
|
|
133
|
+
export { discordRenderer };
|
|
134
|
+
//# sourceMappingURL=discord-DAoUZqvE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-DAoUZqvE.js","names":[],"sources":["../src/renderers/discord.ts"],"sourcesContent":["import type {\n DocChild,\n DocNode,\n DocumentRenderer,\n RenderOptions,\n TableColumn,\n} from '../types'\n\n/**\n * Discord renderer — outputs embed JSON for Discord webhooks/bots.\n * Uses Discord's markdown subset and embed structure.\n */\n\nfunction resolveColumn(col: string | TableColumn): TableColumn {\n return typeof col === 'string' ? { header: col } : col\n}\n\nfunction getTextContent(children: DocChild[]): string {\n return children\n .map((c) =>\n typeof c === 'string' ? c : getTextContent((c as DocNode).children),\n )\n .join('')\n}\n\ninterface DiscordField {\n name: string\n value: string\n inline?: boolean\n}\n\n/** Extract the first h1 title and first HTTP image from the tree. */\nfunction extractMeta(node: DocNode): { title?: string; imageUrl?: string } {\n if (node.type === 'heading') {\n const level = (node.props.level as number) ?? 1\n if (level === 1) return { title: getTextContent(node.children) }\n }\n if (node.type === 'image') {\n const src = node.props.src as string\n if (src.startsWith('http')) return { imageUrl: src }\n }\n for (const child of node.children) {\n if (typeof child !== 'string') {\n const result = extractMeta(child)\n if (result.title || result.imageUrl) return result\n }\n }\n return {}\n}\n\nfunction nodeToMarkdown(\n node: DocNode,\n meta: { title?: string },\n): { content: string; fields: DiscordField[] } {\n const p = node.props\n let content = ''\n const fields: DiscordField[] = []\n\n switch (node.type) {\n case 'document':\n case 'page':\n case 'section':\n case 'row':\n case 'column':\n for (const child of node.children) {\n if (typeof child !== 'string') {\n const result = nodeToMarkdown(child, meta)\n content += result.content\n fields.push(...result.fields)\n }\n }\n break\n\n case 'heading': {\n const text = getTextContent(node.children)\n const level = (p.level as number) ?? 1\n // Skip the first h1 — it's used as embed title\n if (level === 1 && text === meta.title) {\n break\n }\n content += `**${text}**\\n\\n`\n break\n }\n\n case 'text': {\n let text = getTextContent(node.children)\n if (p.bold) text = `**${text}**`\n if (p.italic) text = `*${text}*`\n if (p.strikethrough) text = `~~${text}~~`\n content += `${text}\\n\\n`\n break\n }\n\n case 'link': {\n const href = p.href as string\n const text = getTextContent(node.children)\n content += `[${text}](${href})\\n\\n`\n break\n }\n\n case 'image':\n // Image handled via extractMeta — embedded as embed.image\n break\n\n case 'table': {\n const columns = ((p.columns ?? []) as (string | TableColumn)[]).map(\n resolveColumn,\n )\n const rows = (p.rows ?? []) as (string | number)[][]\n\n // Use Discord embed fields for small tables\n if (columns.length <= 3 && rows.length <= 10) {\n for (const col of columns) {\n const colIdx = columns.indexOf(col)\n const values = rows.map((row) => String(row[colIdx] ?? '')).join('\\n')\n fields.push({\n name: col.header,\n value: values || '-',\n inline: true,\n })\n }\n } else {\n // Fallback to code block for large tables\n const header = columns.map((c) => c.header).join(' | ')\n const separator = columns.map(() => '---').join(' | ')\n const body = rows\n .map((row) => row.map((c) => String(c ?? '')).join(' | '))\n .join('\\n')\n content += `\\`\\`\\`\\n${header}\\n${separator}\\n${body}\\n\\`\\`\\`\\n\\n`\n }\n break\n }\n\n case 'list': {\n const ordered = p.ordered as boolean | undefined\n const items = node.children\n .filter((c): c is DocNode => typeof c !== 'string')\n .map((item, i) => {\n const prefix = ordered ? `${i + 1}.` : '•'\n return `${prefix} ${getTextContent(item.children)}`\n })\n .join('\\n')\n content += `${items}\\n\\n`\n break\n }\n\n case 'code': {\n const lang = (p.language as string) ?? ''\n const text = getTextContent(node.children)\n content += `\\`\\`\\`${lang}\\n${text}\\n\\`\\`\\`\\n\\n`\n break\n }\n\n case 'divider':\n case 'page-break':\n content += '───────────\\n\\n'\n break\n\n case 'button': {\n const href = p.href as string\n const text = getTextContent(node.children)\n content += `[**${text}**](${href})\\n\\n`\n break\n }\n\n case 'quote': {\n const text = getTextContent(node.children)\n content += `> ${text}\\n\\n`\n break\n }\n }\n\n return { content, fields }\n}\n\nexport const discordRenderer: DocumentRenderer = {\n async render(node: DocNode, _options?: RenderOptions): Promise<string> {\n const meta = extractMeta(node)\n const { content, fields } = nodeToMarkdown(node, meta)\n\n const embed: Record<string, unknown> = {\n title: meta.title ?? (node.props.title as string) ?? undefined,\n description: content.trim() || undefined,\n color: 0x4f46e5,\n }\n\n if (fields.length > 0) embed.fields = fields\n if (meta.imageUrl) embed.image = { url: meta.imageUrl }\n\n return JSON.stringify({ embeds: [embed] }, null, 2)\n },\n}\n"],"mappings":"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"}
|