@pyreon/document 0.9.0 → 0.11.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/lib/analysis/index.js.html +1 -1
- package/lib/confluence-Bd3ua1Ut.js.map +1 -1
- package/lib/csv-COrS4qdy.js.map +1 -1
- package/lib/discord-BLUnkEh9.js.map +1 -1
- package/lib/{dist-BsqdI2nY.js → dist-CYL41kqQ.js} +2 -2
- package/lib/dist-CYL41kqQ.js.map +1 -0
- package/lib/{docx-BEBOihjl.js → docx-uNAel545.js} +7 -2
- package/lib/docx-uNAel545.js.map +1 -0
- package/lib/email-D0bbfWq4.js.map +1 -1
- package/lib/{exceljs-BoIDUUaw.js → exceljs-BYETsesT.js} +314 -314
- package/lib/exceljs-BYETsesT.js.map +1 -0
- package/lib/google-chat-CkKCBUWC.js.map +1 -1
- package/lib/html-B5biprN2.js.map +1 -1
- package/lib/index.js +17 -8
- package/lib/index.js.map +1 -1
- package/lib/markdown-CdtlFGC0.js.map +1 -1
- package/lib/notion-iG2C5bEY.js.map +1 -1
- package/lib/{pdf-DIUQUEdj.js → pdf-IuBgTb3T.js} +9 -3
- package/lib/pdf-IuBgTb3T.js.map +1 -0
- package/lib/{pdfmake-DnmLxK4Q.js → pdfmake-CKMX5URW.js} +2 -4
- package/lib/pdfmake-CKMX5URW.js.map +1 -0
- package/lib/{pptx-Dd33oL3_.js → pptx-DXiMiYFM.js} +7 -2
- package/lib/pptx-DXiMiYFM.js.map +1 -0
- package/lib/{pptxgen.es-COcgXsyx.js → pptxgen.es-FsqHs8mD.js} +3 -6
- package/lib/pptxgen.es-FsqHs8mD.js.map +1 -0
- package/lib/sanitize-O_3j1mNJ.js.map +1 -1
- package/lib/slack-BI3EQwYm.js.map +1 -1
- package/lib/svg-BKxumy-p.js.map +1 -1
- package/lib/teams-Cwz9lce0.js.map +1 -1
- package/lib/telegram-gYFqyMXb.js.map +1 -1
- package/lib/text-l1XNXBOC.js.map +1 -1
- package/lib/types/index.d.ts +43 -39
- package/lib/types/index.d.ts.map +1 -1
- package/lib/{vfs_fonts-Df1kkZ4Y.js → vfs_fonts-Cap07Jg3.js} +2 -2
- package/lib/vfs_fonts-Cap07Jg3.js.map +1 -0
- package/lib/whatsapp-CjSGoOKx.js.map +1 -1
- package/lib/{xlsx-Bb5TWyXQ.js → xlsx-Cvu4LBNy.js} +8 -2
- package/lib/xlsx-Cvu4LBNy.js.map +1 -0
- package/package.json +19 -7
- package/src/builder.ts +53 -44
- package/src/download.ts +32 -36
- package/src/env.d.ts +3 -17
- package/src/index.ts +6 -8
- package/src/nodes.ts +45 -45
- package/src/render.ts +45 -118
- package/src/renderers/confluence.ts +64 -80
- package/src/renderers/csv.ts +11 -18
- package/src/renderers/discord.ts +38 -50
- package/src/renderers/docx.ts +78 -120
- package/src/renderers/email.ts +73 -92
- package/src/renderers/google-chat.ts +35 -47
- package/src/renderers/html.ts +78 -101
- package/src/renderers/markdown.ts +43 -53
- package/src/renderers/notion.ts +63 -85
- package/src/renderers/pdf.ts +92 -115
- package/src/renderers/pptx.ts +60 -66
- package/src/renderers/slack.ts +49 -61
- package/src/renderers/svg.ts +49 -63
- package/src/renderers/teams.ts +68 -80
- package/src/renderers/telegram.ts +40 -54
- package/src/renderers/text.ts +44 -66
- package/src/renderers/whatsapp.ts +34 -48
- package/src/renderers/xlsx.ts +47 -61
- package/src/sanitize.ts +21 -25
- package/src/tests/document.test.ts +1337 -1385
- package/src/tests/stress.test.ts +350 -0
- package/src/types.ts +66 -65
- package/lib/dist-BsqdI2nY.js.map +0 -1
- package/lib/docx-BEBOihjl.js.map +0 -1
- package/lib/exceljs-BoIDUUaw.js.map +0 -1
- package/lib/pdf-DIUQUEdj.js.map +0 -1
- package/lib/pdfmake-DnmLxK4Q.js.map +0 -1
- package/lib/pptx-Dd33oL3_.js.map +0 -1
- package/lib/pptxgen.es-COcgXsyx.js.map +0 -1
- package/lib/vfs_fonts-Df1kkZ4Y.js.map +0 -1
- package/lib/xlsx-Bb5TWyXQ.js.map +0 -1
package/src/renderers/notion.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import { sanitizeHref, sanitizeImageSrc } from
|
|
2
|
-
import type {
|
|
3
|
-
DocChild,
|
|
4
|
-
DocNode,
|
|
5
|
-
DocumentRenderer,
|
|
6
|
-
RenderOptions,
|
|
7
|
-
TableColumn,
|
|
8
|
-
} from '../types'
|
|
1
|
+
import { sanitizeHref, sanitizeImageSrc } from "../sanitize"
|
|
2
|
+
import type { DocChild, DocNode, DocumentRenderer, RenderOptions, TableColumn } from "../types"
|
|
9
3
|
|
|
10
4
|
/**
|
|
11
5
|
* Notion renderer — outputs Notion Block JSON for the Notion API.
|
|
@@ -13,19 +7,17 @@ import type {
|
|
|
13
7
|
*/
|
|
14
8
|
|
|
15
9
|
function resolveColumn(col: string | TableColumn): TableColumn {
|
|
16
|
-
return typeof col ===
|
|
10
|
+
return typeof col === "string" ? { header: col } : col
|
|
17
11
|
}
|
|
18
12
|
|
|
19
13
|
function getTextContent(children: DocChild[]): string {
|
|
20
14
|
return children
|
|
21
|
-
.map((c) =>
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
.join('')
|
|
15
|
+
.map((c) => (typeof c === "string" ? c : getTextContent((c as DocNode).children)))
|
|
16
|
+
.join("")
|
|
25
17
|
}
|
|
26
18
|
|
|
27
19
|
interface RichText {
|
|
28
|
-
type:
|
|
20
|
+
type: "text"
|
|
29
21
|
text: { content: string; link?: { url: string } }
|
|
30
22
|
annotations?: {
|
|
31
23
|
bold?: boolean
|
|
@@ -36,13 +28,10 @@ interface RichText {
|
|
|
36
28
|
}
|
|
37
29
|
}
|
|
38
30
|
|
|
39
|
-
function textToRichText(
|
|
40
|
-
text: string,
|
|
41
|
-
annotations?: RichText['annotations'],
|
|
42
|
-
): RichText[] {
|
|
31
|
+
function textToRichText(text: string, annotations?: RichText["annotations"]): RichText[] {
|
|
43
32
|
return [
|
|
44
33
|
{
|
|
45
|
-
type:
|
|
34
|
+
type: "text",
|
|
46
35
|
text: { content: text },
|
|
47
36
|
...(annotations ? { annotations } : {}),
|
|
48
37
|
},
|
|
@@ -50,7 +39,7 @@ function textToRichText(
|
|
|
50
39
|
}
|
|
51
40
|
|
|
52
41
|
interface NotionBlock {
|
|
53
|
-
object:
|
|
42
|
+
object: "block"
|
|
54
43
|
type: string
|
|
55
44
|
[key: string]: unknown
|
|
56
45
|
}
|
|
@@ -60,41 +49,40 @@ function nodeToBlocks(node: DocNode): NotionBlock[] {
|
|
|
60
49
|
const blocks: NotionBlock[] = []
|
|
61
50
|
|
|
62
51
|
switch (node.type) {
|
|
63
|
-
case
|
|
64
|
-
case
|
|
65
|
-
case
|
|
66
|
-
case
|
|
67
|
-
case
|
|
52
|
+
case "document":
|
|
53
|
+
case "page":
|
|
54
|
+
case "section":
|
|
55
|
+
case "row":
|
|
56
|
+
case "column":
|
|
68
57
|
for (const child of node.children) {
|
|
69
|
-
if (typeof child !==
|
|
58
|
+
if (typeof child !== "string") {
|
|
70
59
|
blocks.push(...nodeToBlocks(child))
|
|
71
60
|
}
|
|
72
61
|
}
|
|
73
62
|
break
|
|
74
63
|
|
|
75
|
-
case
|
|
64
|
+
case "heading": {
|
|
76
65
|
const level = (p.level as number) ?? 1
|
|
77
66
|
const text = getTextContent(node.children)
|
|
78
|
-
const type =
|
|
79
|
-
level <= 1 ? 'heading_1' : level === 2 ? 'heading_2' : 'heading_3'
|
|
67
|
+
const type = level <= 1 ? "heading_1" : level === 2 ? "heading_2" : "heading_3"
|
|
80
68
|
blocks.push({
|
|
81
|
-
object:
|
|
69
|
+
object: "block",
|
|
82
70
|
type,
|
|
83
71
|
[type]: { rich_text: textToRichText(text) },
|
|
84
72
|
})
|
|
85
73
|
break
|
|
86
74
|
}
|
|
87
75
|
|
|
88
|
-
case
|
|
76
|
+
case "text": {
|
|
89
77
|
const text = getTextContent(node.children)
|
|
90
|
-
const annotations: RichText[
|
|
78
|
+
const annotations: RichText["annotations"] = {}
|
|
91
79
|
if (p.bold) annotations.bold = true
|
|
92
80
|
if (p.italic) annotations.italic = true
|
|
93
81
|
if (p.strikethrough) annotations.strikethrough = true
|
|
94
82
|
if (p.underline) annotations.underline = true
|
|
95
83
|
blocks.push({
|
|
96
|
-
object:
|
|
97
|
-
type:
|
|
84
|
+
object: "block",
|
|
85
|
+
type: "paragraph",
|
|
98
86
|
paragraph: {
|
|
99
87
|
rich_text: textToRichText(
|
|
100
88
|
text,
|
|
@@ -105,72 +93,64 @@ function nodeToBlocks(node: DocNode): NotionBlock[] {
|
|
|
105
93
|
break
|
|
106
94
|
}
|
|
107
95
|
|
|
108
|
-
case
|
|
96
|
+
case "link": {
|
|
109
97
|
const href = sanitizeHref(p.href as string)
|
|
110
98
|
const text = getTextContent(node.children)
|
|
111
99
|
blocks.push({
|
|
112
|
-
object:
|
|
113
|
-
type:
|
|
100
|
+
object: "block",
|
|
101
|
+
type: "paragraph",
|
|
114
102
|
paragraph: {
|
|
115
|
-
rich_text: [
|
|
116
|
-
{ type: 'text', text: { content: text, link: { url: href } } },
|
|
117
|
-
],
|
|
103
|
+
rich_text: [{ type: "text", text: { content: text, link: { url: href } } }],
|
|
118
104
|
},
|
|
119
105
|
})
|
|
120
106
|
break
|
|
121
107
|
}
|
|
122
108
|
|
|
123
|
-
case
|
|
109
|
+
case "image": {
|
|
124
110
|
const src = sanitizeImageSrc(p.src as string)
|
|
125
|
-
if (src.startsWith(
|
|
111
|
+
if (src.startsWith("http")) {
|
|
126
112
|
blocks.push({
|
|
127
|
-
object:
|
|
128
|
-
type:
|
|
113
|
+
object: "block",
|
|
114
|
+
type: "image",
|
|
129
115
|
image: {
|
|
130
|
-
type:
|
|
116
|
+
type: "external",
|
|
131
117
|
external: { url: src },
|
|
132
|
-
...(p.caption
|
|
133
|
-
? { caption: textToRichText(p.caption as string) }
|
|
134
|
-
: {}),
|
|
118
|
+
...(p.caption ? { caption: textToRichText(p.caption as string) } : {}),
|
|
135
119
|
},
|
|
136
120
|
})
|
|
137
121
|
}
|
|
138
122
|
break
|
|
139
123
|
}
|
|
140
124
|
|
|
141
|
-
case
|
|
142
|
-
const columns = ((p.columns ?? []) as (string | TableColumn)[]).map(
|
|
143
|
-
resolveColumn,
|
|
144
|
-
)
|
|
125
|
+
case "table": {
|
|
126
|
+
const columns = ((p.columns ?? []) as (string | TableColumn)[]).map(resolveColumn)
|
|
145
127
|
const rows = (p.rows ?? []) as (string | number)[][]
|
|
146
128
|
|
|
147
129
|
const tableRows: NotionBlock[] = []
|
|
148
130
|
|
|
149
131
|
// Header row
|
|
150
132
|
tableRows.push({
|
|
151
|
-
object:
|
|
152
|
-
type:
|
|
133
|
+
object: "block",
|
|
134
|
+
type: "table_row",
|
|
153
135
|
table_row: {
|
|
154
|
-
cells: columns.map((col) =>
|
|
155
|
-
textToRichText(col.header, { bold: true }),
|
|
156
|
-
),
|
|
136
|
+
cells: columns.map((col) => textToRichText(col.header, { bold: true })),
|
|
157
137
|
},
|
|
158
138
|
})
|
|
159
139
|
|
|
160
140
|
// Data rows
|
|
161
141
|
for (const row of rows) {
|
|
162
142
|
tableRows.push({
|
|
163
|
-
object:
|
|
164
|
-
type:
|
|
143
|
+
object: "block",
|
|
144
|
+
type: "table_row",
|
|
165
145
|
table_row: {
|
|
166
|
-
cells: columns.map((_, i) => textToRichText(String(row[i] ??
|
|
146
|
+
cells: columns.map((_, i) => textToRichText(String(row[i] ?? ""))),
|
|
167
147
|
},
|
|
168
148
|
})
|
|
169
149
|
}
|
|
170
150
|
|
|
171
151
|
blocks.push({
|
|
172
|
-
object:
|
|
173
|
-
type:
|
|
152
|
+
object: "block",
|
|
153
|
+
type: "table",
|
|
174
154
|
table: {
|
|
175
155
|
table_width: columns.length,
|
|
176
156
|
has_column_header: true,
|
|
@@ -180,16 +160,14 @@ function nodeToBlocks(node: DocNode): NotionBlock[] {
|
|
|
180
160
|
break
|
|
181
161
|
}
|
|
182
162
|
|
|
183
|
-
case
|
|
163
|
+
case "list": {
|
|
184
164
|
const ordered = p.ordered as boolean | undefined
|
|
185
|
-
const items = node.children.filter(
|
|
186
|
-
(c): c is DocNode => typeof c !== 'string',
|
|
187
|
-
)
|
|
165
|
+
const items = node.children.filter((c): c is DocNode => typeof c !== "string")
|
|
188
166
|
for (const item of items) {
|
|
189
167
|
const text = getTextContent(item.children)
|
|
190
|
-
const type = ordered ?
|
|
168
|
+
const type = ordered ? "numbered_list_item" : "bulleted_list_item"
|
|
191
169
|
blocks.push({
|
|
192
|
-
object:
|
|
170
|
+
object: "block",
|
|
193
171
|
type,
|
|
194
172
|
[type]: { rich_text: textToRichText(text) },
|
|
195
173
|
})
|
|
@@ -197,12 +175,12 @@ function nodeToBlocks(node: DocNode): NotionBlock[] {
|
|
|
197
175
|
break
|
|
198
176
|
}
|
|
199
177
|
|
|
200
|
-
case
|
|
178
|
+
case "code": {
|
|
201
179
|
const text = getTextContent(node.children)
|
|
202
|
-
const lang = (p.language as string) ??
|
|
180
|
+
const lang = (p.language as string) ?? "plain text"
|
|
203
181
|
blocks.push({
|
|
204
|
-
object:
|
|
205
|
-
type:
|
|
182
|
+
object: "block",
|
|
183
|
+
type: "code",
|
|
206
184
|
code: {
|
|
207
185
|
rich_text: textToRichText(text),
|
|
208
186
|
language: lang,
|
|
@@ -211,29 +189,29 @@ function nodeToBlocks(node: DocNode): NotionBlock[] {
|
|
|
211
189
|
break
|
|
212
190
|
}
|
|
213
191
|
|
|
214
|
-
case
|
|
215
|
-
case
|
|
216
|
-
blocks.push({ object:
|
|
192
|
+
case "divider":
|
|
193
|
+
case "page-break":
|
|
194
|
+
blocks.push({ object: "block", type: "divider", divider: {} })
|
|
217
195
|
break
|
|
218
196
|
|
|
219
|
-
case
|
|
197
|
+
case "spacer":
|
|
220
198
|
blocks.push({
|
|
221
|
-
object:
|
|
222
|
-
type:
|
|
199
|
+
object: "block",
|
|
200
|
+
type: "paragraph",
|
|
223
201
|
paragraph: { rich_text: [] },
|
|
224
202
|
})
|
|
225
203
|
break
|
|
226
204
|
|
|
227
|
-
case
|
|
205
|
+
case "button": {
|
|
228
206
|
const href = sanitizeHref(p.href as string)
|
|
229
207
|
const text = getTextContent(node.children)
|
|
230
208
|
blocks.push({
|
|
231
|
-
object:
|
|
232
|
-
type:
|
|
209
|
+
object: "block",
|
|
210
|
+
type: "paragraph",
|
|
233
211
|
paragraph: {
|
|
234
212
|
rich_text: [
|
|
235
213
|
{
|
|
236
|
-
type:
|
|
214
|
+
type: "text",
|
|
237
215
|
text: { content: text, link: { url: href } },
|
|
238
216
|
annotations: { bold: true },
|
|
239
217
|
},
|
|
@@ -243,11 +221,11 @@ function nodeToBlocks(node: DocNode): NotionBlock[] {
|
|
|
243
221
|
break
|
|
244
222
|
}
|
|
245
223
|
|
|
246
|
-
case
|
|
224
|
+
case "quote": {
|
|
247
225
|
const text = getTextContent(node.children)
|
|
248
226
|
blocks.push({
|
|
249
|
-
object:
|
|
250
|
-
type:
|
|
227
|
+
object: "block",
|
|
228
|
+
type: "quote",
|
|
251
229
|
quote: { rich_text: textToRichText(text) },
|
|
252
230
|
})
|
|
253
231
|
break
|