@pyreon/document 0.11.5 → 0.11.6

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.
Files changed (50) hide show
  1. package/README.md +7 -4
  2. package/lib/confluence-Bd3ua1Ut.js.map +1 -1
  3. package/lib/csv-COrS4qdy.js.map +1 -1
  4. package/lib/discord-BLUnkEh9.js.map +1 -1
  5. package/lib/docx-uNAel545.js.map +1 -1
  6. package/lib/email-D0bbfWq4.js.map +1 -1
  7. package/lib/google-chat-CkKCBUWC.js.map +1 -1
  8. package/lib/html-B5biprN2.js.map +1 -1
  9. package/lib/index.js.map +1 -1
  10. package/lib/markdown-CdtlFGC0.js.map +1 -1
  11. package/lib/notion-iG2C5bEY.js.map +1 -1
  12. package/lib/pdf-IuBgTb3T.js.map +1 -1
  13. package/lib/pptx-DXiMiYFM.js.map +1 -1
  14. package/lib/sanitize-O_3j1mNJ.js.map +1 -1
  15. package/lib/slack-BI3EQwYm.js.map +1 -1
  16. package/lib/svg-BKxumy-p.js.map +1 -1
  17. package/lib/teams-Cwz9lce0.js.map +1 -1
  18. package/lib/telegram-gYFqyMXb.js.map +1 -1
  19. package/lib/text-l1XNXBOC.js.map +1 -1
  20. package/lib/types/index.d.ts +27 -27
  21. package/lib/whatsapp-CjSGoOKx.js.map +1 -1
  22. package/lib/xlsx-Cvu4LBNy.js.map +1 -1
  23. package/package.json +21 -21
  24. package/src/builder.ts +36 -36
  25. package/src/download.ts +32 -32
  26. package/src/index.ts +5 -10
  27. package/src/nodes.ts +45 -45
  28. package/src/render.ts +43 -43
  29. package/src/renderers/confluence.ts +63 -63
  30. package/src/renderers/csv.ts +10 -10
  31. package/src/renderers/discord.ts +37 -37
  32. package/src/renderers/docx.ts +57 -57
  33. package/src/renderers/email.ts +72 -72
  34. package/src/renderers/google-chat.ts +34 -34
  35. package/src/renderers/html.ts +76 -76
  36. package/src/renderers/markdown.ts +42 -42
  37. package/src/renderers/notion.ts +60 -60
  38. package/src/renderers/pdf.ts +78 -78
  39. package/src/renderers/pptx.ts +51 -51
  40. package/src/renderers/slack.ts +48 -48
  41. package/src/renderers/svg.ts +47 -47
  42. package/src/renderers/teams.ts +67 -67
  43. package/src/renderers/telegram.ts +39 -39
  44. package/src/renderers/text.ts +43 -43
  45. package/src/renderers/whatsapp.ts +33 -33
  46. package/src/renderers/xlsx.ts +35 -35
  47. package/src/sanitize.ts +20 -20
  48. package/src/tests/document.test.ts +1302 -1302
  49. package/src/tests/stress.test.ts +110 -110
  50. package/src/types.ts +61 -61
package/src/builder.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { download } from "./download"
1
+ import { download } from './download'
2
2
  import {
3
3
  Button,
4
4
  Code,
@@ -16,8 +16,8 @@ import {
16
16
  Spacer,
17
17
  Table,
18
18
  Text,
19
- } from "./nodes"
20
- import { render } from "./render"
19
+ } from './nodes'
20
+ import { render } from './render'
21
21
  import type {
22
22
  ButtonProps,
23
23
  CodeProps,
@@ -33,7 +33,7 @@ import type {
33
33
  RenderOptions,
34
34
  TableProps,
35
35
  TextProps,
36
- } from "./types"
36
+ } from './types'
37
37
 
38
38
  /**
39
39
  * Create a document using the builder pattern — no JSX needed.
@@ -57,21 +57,21 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
57
57
  }
58
58
 
59
59
  const builder: DocumentBuilder = {
60
- heading(text: string, p?: Omit<HeadingProps, "children">) {
60
+ heading(text: string, p?: Omit<HeadingProps, 'children'>) {
61
61
  sections.push(Heading({ ...p, children: text }))
62
62
  return builder
63
63
  },
64
64
 
65
- text(text: string, p?: Omit<TextProps, "children">) {
65
+ text(text: string, p?: Omit<TextProps, 'children'>) {
66
66
  sections.push(Text({ ...p, children: text }))
67
67
  return builder
68
68
  },
69
69
 
70
- paragraph(text: string, p?: Omit<TextProps, "children">) {
70
+ paragraph(text: string, p?: Omit<TextProps, 'children'>) {
71
71
  return builder.text(text, p)
72
72
  },
73
73
 
74
- image(src: string, p?: Omit<ImageProps, "src">) {
74
+ image(src: string, p?: Omit<ImageProps, 'src'>) {
75
75
  sections.push(Image({ src, ...p }))
76
76
  return builder
77
77
  },
@@ -81,7 +81,7 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
81
81
  return builder
82
82
  },
83
83
 
84
- list(items: string[], p?: Omit<ListProps, "children">) {
84
+ list(items: string[], p?: Omit<ListProps, 'children'>) {
85
85
  sections.push(
86
86
  List({
87
87
  ...p,
@@ -91,7 +91,7 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
91
91
  return builder
92
92
  },
93
93
 
94
- code(text: string, p?: Omit<CodeProps, "children">) {
94
+ code(text: string, p?: Omit<CodeProps, 'children'>) {
95
95
  sections.push(Code({ ...p, children: text }))
96
96
  return builder
97
97
  },
@@ -106,17 +106,17 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
106
106
  return builder
107
107
  },
108
108
 
109
- quote(text: string, p?: Omit<QuoteProps, "children">) {
109
+ quote(text: string, p?: Omit<QuoteProps, 'children'>) {
110
110
  sections.push(Quote({ ...p, children: text }))
111
111
  return builder
112
112
  },
113
113
 
114
- button(text: string, p: Omit<ButtonProps, "children">) {
114
+ button(text: string, p: Omit<ButtonProps, 'children'>) {
115
115
  sections.push(Button({ ...p, children: text }))
116
116
  return builder
117
117
  },
118
118
 
119
- link(text: string, p: Omit<LinkProps, "children">) {
119
+ link(text: string, p: Omit<LinkProps, 'children'>) {
120
120
  sections.push(Link({ ...p, children: text }))
121
121
  return builder
122
122
  },
@@ -144,7 +144,7 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
144
144
  // Try to get data URL from chart instance
145
145
  const inst = instance as { getDataURL?: (opts: unknown) => string }
146
146
  if (inst?.getDataURL) {
147
- const dataUrl = inst.getDataURL({ type: "png", pixelRatio: 2 })
147
+ const dataUrl = inst.getDataURL({ type: 'png', pixelRatio: 2 })
148
148
  sections.push(
149
149
  Image({
150
150
  src: dataUrl,
@@ -156,9 +156,9 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
156
156
  } else {
157
157
  sections.push(
158
158
  Text({
159
- children: "[Chart]",
159
+ children: '[Chart]',
160
160
  italic: true,
161
- color: "#999",
161
+ color: '#999',
162
162
  } as TextProps & { children: string }),
163
163
  )
164
164
  }
@@ -181,9 +181,9 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
181
181
  } else {
182
182
  sections.push(
183
183
  Text({
184
- children: "[Flow Diagram]",
184
+ children: '[Flow Diagram]',
185
185
  italic: true,
186
- color: "#999",
186
+ color: '#999',
187
187
  } as TextProps & { children: string }),
188
188
  )
189
189
  }
@@ -195,75 +195,75 @@ export function createDocument(props: DocumentProps = {}): DocumentBuilder {
195
195
  },
196
196
 
197
197
  async toHtml(options?: RenderOptions) {
198
- return render(getNode(), "html", options) as Promise<string>
198
+ return render(getNode(), 'html', options) as Promise<string>
199
199
  },
200
200
 
201
201
  async toPdf(options?: RenderOptions) {
202
- return render(getNode(), "pdf", options) as Promise<Uint8Array>
202
+ return render(getNode(), 'pdf', options) as Promise<Uint8Array>
203
203
  },
204
204
 
205
205
  async toDocx(options?: RenderOptions) {
206
- return render(getNode(), "docx", options) as Promise<Uint8Array>
206
+ return render(getNode(), 'docx', options) as Promise<Uint8Array>
207
207
  },
208
208
 
209
209
  async toEmail(options?: RenderOptions) {
210
- return render(getNode(), "email", options) as Promise<string>
210
+ return render(getNode(), 'email', options) as Promise<string>
211
211
  },
212
212
 
213
213
  async toPptx(options?: RenderOptions) {
214
- return render(getNode(), "pptx", options) as Promise<Uint8Array>
214
+ return render(getNode(), 'pptx', options) as Promise<Uint8Array>
215
215
  },
216
216
 
217
217
  async toXlsx(options?: RenderOptions) {
218
- return render(getNode(), "xlsx", options) as Promise<Uint8Array>
218
+ return render(getNode(), 'xlsx', options) as Promise<Uint8Array>
219
219
  },
220
220
 
221
221
  async toMarkdown(options?: RenderOptions) {
222
- return render(getNode(), "md", options) as Promise<string>
222
+ return render(getNode(), 'md', options) as Promise<string>
223
223
  },
224
224
 
225
225
  async toText(options?: RenderOptions) {
226
- return render(getNode(), "text", options) as Promise<string>
226
+ return render(getNode(), 'text', options) as Promise<string>
227
227
  },
228
228
 
229
229
  async toCsv(options?: RenderOptions) {
230
- return render(getNode(), "csv", options) as Promise<string>
230
+ return render(getNode(), 'csv', options) as Promise<string>
231
231
  },
232
232
 
233
233
  async toSlack(options?: RenderOptions) {
234
- return render(getNode(), "slack", options) as Promise<string>
234
+ return render(getNode(), 'slack', options) as Promise<string>
235
235
  },
236
236
 
237
237
  async toSvg(options?: RenderOptions) {
238
- return render(getNode(), "svg", options) as Promise<string>
238
+ return render(getNode(), 'svg', options) as Promise<string>
239
239
  },
240
240
 
241
241
  async toTeams(options?: RenderOptions) {
242
- return render(getNode(), "teams", options) as Promise<string>
242
+ return render(getNode(), 'teams', options) as Promise<string>
243
243
  },
244
244
 
245
245
  async toDiscord(options?: RenderOptions) {
246
- return render(getNode(), "discord", options) as Promise<string>
246
+ return render(getNode(), 'discord', options) as Promise<string>
247
247
  },
248
248
 
249
249
  async toTelegram(options?: RenderOptions) {
250
- return render(getNode(), "telegram", options) as Promise<string>
250
+ return render(getNode(), 'telegram', options) as Promise<string>
251
251
  },
252
252
 
253
253
  async toNotion(options?: RenderOptions) {
254
- return render(getNode(), "notion", options) as Promise<string>
254
+ return render(getNode(), 'notion', options) as Promise<string>
255
255
  },
256
256
 
257
257
  async toConfluence(options?: RenderOptions) {
258
- return render(getNode(), "confluence", options) as Promise<string>
258
+ return render(getNode(), 'confluence', options) as Promise<string>
259
259
  },
260
260
 
261
261
  async toWhatsApp(options?: RenderOptions) {
262
- return render(getNode(), "whatsapp", options) as Promise<string>
262
+ return render(getNode(), 'whatsapp', options) as Promise<string>
263
263
  },
264
264
 
265
265
  async toGoogleChat(options?: RenderOptions) {
266
- return render(getNode(), "google-chat", options) as Promise<string>
266
+ return render(getNode(), 'google-chat', options) as Promise<string>
267
267
  },
268
268
 
269
269
  async download(filename: string, options?: RenderOptions) {
package/src/download.ts CHANGED
@@ -1,33 +1,33 @@
1
- import { render } from "./render"
2
- import type { DocNode, RenderOptions } from "./types"
1
+ import { render } from './render'
2
+ import type { DocNode, RenderOptions } from './types'
3
3
 
4
4
  const FORMAT_MAP: Record<string, string> = {
5
- html: "html",
6
- htm: "html",
7
- pdf: "pdf",
8
- docx: "docx",
9
- doc: "docx",
10
- xlsx: "xlsx",
11
- xls: "xlsx",
12
- pptx: "pptx",
13
- ppt: "pptx",
14
- md: "md",
15
- txt: "text",
16
- csv: "csv",
17
- svg: "svg",
5
+ html: 'html',
6
+ htm: 'html',
7
+ pdf: 'pdf',
8
+ docx: 'docx',
9
+ doc: 'docx',
10
+ xlsx: 'xlsx',
11
+ xls: 'xlsx',
12
+ pptx: 'pptx',
13
+ ppt: 'pptx',
14
+ md: 'md',
15
+ txt: 'text',
16
+ csv: 'csv',
17
+ svg: 'svg',
18
18
  }
19
19
 
20
20
  const MIME_TYPES: Record<string, string> = {
21
- html: "text/html",
22
- pdf: "application/pdf",
23
- docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
24
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
25
- pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
26
- email: "text/html",
27
- md: "text/markdown",
28
- text: "text/plain",
29
- csv: "text/csv",
30
- svg: "image/svg+xml",
21
+ html: 'text/html',
22
+ pdf: 'application/pdf',
23
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
24
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
25
+ pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
26
+ email: 'text/html',
27
+ md: 'text/markdown',
28
+ text: 'text/plain',
29
+ csv: 'text/csv',
30
+ svg: 'image/svg+xml',
31
31
  }
32
32
 
33
33
  /**
@@ -44,15 +44,15 @@ export async function download(
44
44
  filename: string,
45
45
  options?: RenderOptions,
46
46
  ): Promise<void> {
47
- const ext = filename.split(".").pop()?.toLowerCase()
47
+ const ext = filename.split('.').pop()?.toLowerCase()
48
48
  if (!ext) {
49
- throw new Error("[@pyreon/document] Filename must have an extension (e.g., report.pdf).")
49
+ throw new Error('[@pyreon/document] Filename must have an extension (e.g., report.pdf).')
50
50
  }
51
51
 
52
52
  const format = FORMAT_MAP[ext]
53
53
  if (!format) {
54
54
  throw new Error(
55
- `[@pyreon/document] Unknown file extension '.${ext}'. Supported: ${Object.keys(FORMAT_MAP).join(", ")}`,
55
+ `[@pyreon/document] Unknown file extension '.${ext}'. Supported: ${Object.keys(FORMAT_MAP).join(', ')}`,
56
56
  )
57
57
  }
58
58
 
@@ -62,15 +62,15 @@ export async function download(
62
62
  result instanceof Uint8Array
63
63
  ? new Blob([result as BlobPart])
64
64
  : new Blob([result], {
65
- type: MIME_TYPES[format] ?? "application/octet-stream",
65
+ type: MIME_TYPES[format] ?? 'application/octet-stream',
66
66
  })
67
67
 
68
- if (typeof document === "undefined") {
69
- throw new Error("[@pyreon/document] download() requires a browser environment.")
68
+ if (typeof document === 'undefined') {
69
+ throw new Error('[@pyreon/document] download() requires a browser environment.')
70
70
  }
71
71
 
72
72
  const url = URL.createObjectURL(blob)
73
- const a = document.createElement("a")
73
+ const a = document.createElement('a')
74
74
  a.href = url
75
75
  a.download = filename
76
76
  a.click()
package/src/index.ts CHANGED
@@ -28,9 +28,9 @@
28
28
  */
29
29
 
30
30
  // Builder
31
- export { createDocument } from "./builder"
31
+ export { createDocument } from './builder'
32
32
  // Download (browser)
33
- export { download } from "./download"
33
+ export { download } from './download'
34
34
  // Primitives
35
35
  export {
36
36
  Button,
@@ -52,15 +52,10 @@ export {
52
52
  Spacer,
53
53
  Table,
54
54
  Text,
55
- } from "./nodes"
55
+ } from './nodes'
56
56
 
57
57
  // Render
58
- export {
59
- _resetRenderers,
60
- registerRenderer,
61
- render,
62
- unregisterRenderer,
63
- } from "./render"
58
+ export { _resetRenderers, registerRenderer, render, unregisterRenderer } from './render'
64
59
 
65
60
  // Types
66
61
  export type {
@@ -93,4 +88,4 @@ export type {
93
88
  TableColumn,
94
89
  TableProps,
95
90
  TextProps,
96
- } from "./types"
91
+ } from './types'
package/src/nodes.ts CHANGED
@@ -19,7 +19,7 @@ import type {
19
19
  SpacerProps,
20
20
  TableProps,
21
21
  TextProps,
22
- } from "./types"
22
+ } from './types'
23
23
 
24
24
  // ─── Node Constructor ───────────────────────────────────────────────────────
25
25
 
@@ -33,13 +33,13 @@ function createNode(type: NodeType, props: object, children: unknown): DocNode {
33
33
 
34
34
  function normalizeChildren(children: unknown): DocChild[] {
35
35
  if (children == null || children === false) return []
36
- if (typeof children === "string") return [children]
37
- if (typeof children === "number") return [String(children)]
36
+ if (typeof children === 'string') return [children]
37
+ if (typeof children === 'number') return [String(children)]
38
38
  if (Array.isArray(children)) return children.flatMap(normalizeChildren)
39
39
  if (isDocNode(children)) return [children]
40
- if (typeof children === "object") {
40
+ if (typeof children === 'object') {
41
41
  throw new Error(
42
- "[@pyreon/document] Invalid child: plain objects are not valid document children. Use a document node (Text, Heading, etc.) instead.",
42
+ '[@pyreon/document] Invalid child: plain objects are not valid document children. Use a document node (Text, Heading, etc.) instead.',
43
43
  )
44
44
  }
45
45
  return [String(children)]
@@ -48,11 +48,11 @@ function normalizeChildren(children: unknown): DocChild[] {
48
48
  /** Type guard — checks if a value is a DocNode. */
49
49
  export function isDocNode(value: unknown): value is DocNode {
50
50
  return (
51
- typeof value === "object" &&
51
+ typeof value === 'object' &&
52
52
  value !== null &&
53
- "type" in value &&
54
- "props" in value &&
55
- "children" in value
53
+ 'type' in value &&
54
+ 'props' in value &&
55
+ 'children' in value
56
56
  )
57
57
  }
58
58
 
@@ -70,9 +70,9 @@ export function isDocNode(value: unknown): value is DocNode {
70
70
  */
71
71
  export function Document(props: DocumentProps): DocNode {
72
72
  const { children, ...rest } = props
73
- return createNode("document", rest, children)
73
+ return createNode('document', rest, children)
74
74
  }
75
- Document._documentType = "document" as const
75
+ Document._documentType = 'document' as const
76
76
 
77
77
  /**
78
78
  * Page container. Maps to a PDF page, DOCX section, or email block.
@@ -86,9 +86,9 @@ Document._documentType = "document" as const
86
86
  */
87
87
  export function Page(props: PageProps): DocNode {
88
88
  const { children, ...rest } = props
89
- return createNode("page", rest, children)
89
+ return createNode('page', rest, children)
90
90
  }
91
- Page._documentType = "page" as const
91
+ Page._documentType = 'page' as const
92
92
 
93
93
  /**
94
94
  * Layout section — groups content with optional direction, padding, background.
@@ -103,9 +103,9 @@ Page._documentType = "page" as const
103
103
  */
104
104
  export function Section(props: SectionProps): DocNode {
105
105
  const { children, ...rest } = props
106
- return createNode("section", rest, children)
106
+ return createNode('section', rest, children)
107
107
  }
108
- Section._documentType = "section" as const
108
+ Section._documentType = 'section' as const
109
109
 
110
110
  /**
111
111
  * Horizontal layout container.
@@ -120,18 +120,18 @@ Section._documentType = "section" as const
120
120
  */
121
121
  export function Row(props: RowProps): DocNode {
122
122
  const { children, ...rest } = props
123
- return createNode("row", rest, children)
123
+ return createNode('row', rest, children)
124
124
  }
125
- Row._documentType = "row" as const
125
+ Row._documentType = 'row' as const
126
126
 
127
127
  /**
128
128
  * Column within a Row.
129
129
  */
130
130
  export function Column(props: ColumnProps): DocNode {
131
131
  const { children, ...rest } = props
132
- return createNode("column", rest, children)
132
+ return createNode('column', rest, children)
133
133
  }
134
- Column._documentType = "column" as const
134
+ Column._documentType = 'column' as const
135
135
 
136
136
  /**
137
137
  * Heading text (h1–h6).
@@ -144,9 +144,9 @@ Column._documentType = "column" as const
144
144
  */
145
145
  export function Heading(props: HeadingProps): DocNode {
146
146
  const { children, ...rest } = props
147
- return createNode("heading", { level: 1, ...rest }, children)
147
+ return createNode('heading', { level: 1, ...rest }, children)
148
148
  }
149
- Heading._documentType = "heading" as const
149
+ Heading._documentType = 'heading' as const
150
150
 
151
151
  /**
152
152
  * Text paragraph with optional formatting.
@@ -159,9 +159,9 @@ Heading._documentType = "heading" as const
159
159
  */
160
160
  export function Text(props: TextProps): DocNode {
161
161
  const { children, ...rest } = props
162
- return createNode("text", rest, children)
162
+ return createNode('text', rest, children)
163
163
  }
164
- Text._documentType = "text" as const
164
+ Text._documentType = 'text' as const
165
165
 
166
166
  /**
167
167
  * Hyperlink.
@@ -173,9 +173,9 @@ Text._documentType = "text" as const
173
173
  */
174
174
  export function Link(props: LinkProps): DocNode {
175
175
  const { children, ...rest } = props
176
- return createNode("link", rest, children)
176
+ return createNode('link', rest, children)
177
177
  }
178
- Link._documentType = "link" as const
178
+ Link._documentType = 'link' as const
179
179
 
180
180
  /**
181
181
  * Image with optional sizing and caption.
@@ -187,9 +187,9 @@ Link._documentType = "link" as const
187
187
  * ```
188
188
  */
189
189
  export function Image(props: ImageProps): DocNode {
190
- return createNode("image", props, [])
190
+ return createNode('image', props, [])
191
191
  }
192
- Image._documentType = "image" as const
192
+ Image._documentType = 'image' as const
193
193
 
194
194
  /**
195
195
  * Data table with columns and rows.
@@ -205,9 +205,9 @@ Image._documentType = "image" as const
205
205
  * ```
206
206
  */
207
207
  export function Table(props: TableProps): DocNode {
208
- return createNode("table", props, [])
208
+ return createNode('table', props, [])
209
209
  }
210
- Table._documentType = "table" as const
210
+ Table._documentType = 'table' as const
211
211
 
212
212
  /**
213
213
  * Ordered or unordered list.
@@ -222,18 +222,18 @@ Table._documentType = "table" as const
222
222
  */
223
223
  export function List(props: ListProps): DocNode {
224
224
  const { children, ...rest } = props
225
- return createNode("list", rest, children)
225
+ return createNode('list', rest, children)
226
226
  }
227
- List._documentType = "list" as const
227
+ List._documentType = 'list' as const
228
228
 
229
229
  /**
230
230
  * Single list item within a List.
231
231
  */
232
232
  export function ListItem(props: ListItemProps): DocNode {
233
233
  const { children } = props
234
- return createNode("list-item", {}, children)
234
+ return createNode('list-item', {}, children)
235
235
  }
236
- ListItem._documentType = "list-item" as const
236
+ ListItem._documentType = 'list-item' as const
237
237
 
238
238
  /**
239
239
  * Code block with optional language hint.
@@ -245,9 +245,9 @@ ListItem._documentType = "list-item" as const
245
245
  */
246
246
  export function Code(props: CodeProps): DocNode {
247
247
  const { children, ...rest } = props
248
- return createNode("code", rest, children)
248
+ return createNode('code', rest, children)
249
249
  }
250
- Code._documentType = "code" as const
250
+ Code._documentType = 'code' as const
251
251
 
252
252
  /**
253
253
  * Horizontal divider line.
@@ -258,9 +258,9 @@ Code._documentType = "code" as const
258
258
  * ```
259
259
  */
260
260
  export function Divider(props: DividerProps = {}): DocNode {
261
- return createNode("divider", props, [])
261
+ return createNode('divider', props, [])
262
262
  }
263
- Divider._documentType = "divider" as const
263
+ Divider._documentType = 'divider' as const
264
264
 
265
265
  /**
266
266
  * Page break — forces content after this point to the next page (PDF/DOCX)
@@ -272,9 +272,9 @@ Divider._documentType = "divider" as const
272
272
  * ```
273
273
  */
274
274
  export function PageBreak(): DocNode {
275
- return createNode("page-break", {}, [])
275
+ return createNode('page-break', {}, [])
276
276
  }
277
- PageBreak._documentType = "page-break" as const
277
+ PageBreak._documentType = 'page-break' as const
278
278
 
279
279
  /**
280
280
  * Vertical spacer.
@@ -285,9 +285,9 @@ PageBreak._documentType = "page-break" as const
285
285
  * ```
286
286
  */
287
287
  export function Spacer(props: SpacerProps): DocNode {
288
- return createNode("spacer", props, [])
288
+ return createNode('spacer', props, [])
289
289
  }
290
- Spacer._documentType = "spacer" as const
290
+ Spacer._documentType = 'spacer' as const
291
291
 
292
292
  /**
293
293
  * CTA button — renders as a bulletproof button in email, styled link in PDF/DOCX.
@@ -301,9 +301,9 @@ Spacer._documentType = "spacer" as const
301
301
  */
302
302
  export function Button(props: ButtonProps): DocNode {
303
303
  const { children, ...rest } = props
304
- return createNode("button", rest, children)
304
+ return createNode('button', rest, children)
305
305
  }
306
- Button._documentType = "button" as const
306
+ Button._documentType = 'button' as const
307
307
 
308
308
  /**
309
309
  * Block quote.
@@ -315,6 +315,6 @@ Button._documentType = "button" as const
315
315
  */
316
316
  export function Quote(props: QuoteProps): DocNode {
317
317
  const { children, ...rest } = props
318
- return createNode("quote", rest, children)
318
+ return createNode('quote', rest, children)
319
319
  }
320
- Quote._documentType = "quote" as const
320
+ Quote._documentType = 'quote' as const