@pyreon/document 0.12.15 → 0.13.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/package.json +6 -5
- package/src/manifest.ts +150 -0
- package/src/tests/manifest-snapshot.test.ts +86 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/document",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Universal document rendering for Pyreon — one template, every output format (HTML, PDF, DOCX, email, XLSX, Markdown, and more)",
|
|
5
5
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/document#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -42,8 +42,9 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@happy-dom/global-registrator": "^20.8.9",
|
|
45
|
-
"@pyreon/core": "^0.
|
|
46
|
-
"@pyreon/
|
|
45
|
+
"@pyreon/core": "^0.13.0",
|
|
46
|
+
"@pyreon/manifest": "0.13.0",
|
|
47
|
+
"@pyreon/reactivity": "^0.13.0",
|
|
47
48
|
"@types/pdfmake": "^0.3.2",
|
|
48
49
|
"@vitus-labs/tools-lint": "^1.15.5",
|
|
49
50
|
"docx": "^9.6.0",
|
|
@@ -52,8 +53,8 @@
|
|
|
52
53
|
"pptxgenjs": "^4.0.1"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
|
-
"@pyreon/core": "^0.
|
|
56
|
-
"@pyreon/reactivity": "^0.
|
|
56
|
+
"@pyreon/core": "^0.13.0",
|
|
57
|
+
"@pyreon/reactivity": "^0.13.0"
|
|
57
58
|
},
|
|
58
59
|
"optionalDependencies": {
|
|
59
60
|
"docx": "^9.6.0",
|
package/src/manifest.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { defineManifest } from '@pyreon/manifest'
|
|
2
|
+
|
|
3
|
+
export default defineManifest({
|
|
4
|
+
name: '@pyreon/document',
|
|
5
|
+
title: 'Universal Document Rendering',
|
|
6
|
+
tagline:
|
|
7
|
+
'Universal document rendering — 18 primitives, 14+ output formats',
|
|
8
|
+
description:
|
|
9
|
+
'Universal document rendering for Pyreon. One template, every output format: HTML, PDF, DOCX, XLSX, PPTX, email, Markdown, plain text, CSV, SVG, Slack, Teams, Discord, Telegram, Notion, Confluence, WhatsApp, Google Chat. Heavy renderers (PDF ~300KB, DOCX ~100KB, XLSX ~500KB, PPTX ~200KB) are lazy-loaded on demand. Supports both JSX primitives and a fluent builder API.',
|
|
10
|
+
category: 'universal',
|
|
11
|
+
longExample: `import { Document, Page, Heading, Text, Table, Image, List, Code, Divider, render, createDocument, download } from '@pyreon/document'
|
|
12
|
+
|
|
13
|
+
// JSX primitives — compose a document tree
|
|
14
|
+
const report = (
|
|
15
|
+
<Document title="Q4 Sales Report" author="Analytics Team">
|
|
16
|
+
<Page>
|
|
17
|
+
<Heading level={1}>Sales Report</Heading>
|
|
18
|
+
<Text>Q4 2026 performance summary.</Text>
|
|
19
|
+
<Table
|
|
20
|
+
columns={['Region', 'Revenue', 'Growth']}
|
|
21
|
+
rows={[
|
|
22
|
+
['US', '$1.2M', '+15%'],
|
|
23
|
+
['EU', '$800K', '+8%'],
|
|
24
|
+
['APAC', '$500K', '+22%'],
|
|
25
|
+
]}
|
|
26
|
+
/>
|
|
27
|
+
<Divider />
|
|
28
|
+
<Heading level={2}>Notes</Heading>
|
|
29
|
+
<List items={['Record quarter for APAC', 'EU impacted by currency exchange']} />
|
|
30
|
+
<Code language="sql">SELECT region, SUM(revenue) FROM sales GROUP BY region</Code>
|
|
31
|
+
</Page>
|
|
32
|
+
</Document>
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
// Render to any format:
|
|
36
|
+
const pdf = await render(report, 'pdf') // Uint8Array
|
|
37
|
+
const html = await render(report, 'html') // string
|
|
38
|
+
const email = await render(report, 'email') // Outlook-safe HTML
|
|
39
|
+
const docx = await render(report, 'docx') // Uint8Array
|
|
40
|
+
const xlsx = await render(report, 'xlsx') // Uint8Array
|
|
41
|
+
const md = await render(report, 'md') // Markdown string
|
|
42
|
+
const slack = await render(report, 'slack') // Slack Block Kit JSON
|
|
43
|
+
const notion = await render(report, 'notion') // Notion blocks
|
|
44
|
+
const teams = await render(report, 'teams') // Adaptive Card JSON
|
|
45
|
+
|
|
46
|
+
// Browser download helper:
|
|
47
|
+
download(pdf, 'report.pdf')
|
|
48
|
+
|
|
49
|
+
// Builder API — alternative to JSX:
|
|
50
|
+
const doc = createDocument({ title: 'Report' })
|
|
51
|
+
.heading('Sales Report')
|
|
52
|
+
.text('Q4 2026 performance summary.')
|
|
53
|
+
.table({ columns: ['Region', 'Revenue'], rows: [['US', '$1M']] })
|
|
54
|
+
|
|
55
|
+
await doc.toPdf() // PDF
|
|
56
|
+
await doc.toEmail() // email-safe HTML
|
|
57
|
+
await doc.toDocx() // Word document
|
|
58
|
+
await doc.toSlack() // Slack Block Kit
|
|
59
|
+
await doc.toNotion() // Notion blocks`,
|
|
60
|
+
features: [
|
|
61
|
+
'render(node, format, options?) — render to any of 14+ output formats',
|
|
62
|
+
'createDocument(props?) — fluent builder API with .heading(), .text(), .table(), etc.',
|
|
63
|
+
'18 JSX primitives: Document, Page, Heading, Text, Table, Image, List, Code, and more',
|
|
64
|
+
'Heavy renderers lazy-loaded (PDF, DOCX, XLSX, PPTX)',
|
|
65
|
+
'download() helper for browser file downloads',
|
|
66
|
+
'registerRenderer() for custom output formats',
|
|
67
|
+
],
|
|
68
|
+
api: [
|
|
69
|
+
{
|
|
70
|
+
name: 'render',
|
|
71
|
+
kind: 'function',
|
|
72
|
+
signature: '(node: DocNode, format: OutputFormat, options?: RenderOptions) => Promise<RenderResult>',
|
|
73
|
+
summary:
|
|
74
|
+
'Render a document node tree to any supported format. Returns a string (HTML, Markdown, text, CSV, email, Slack, Teams, etc.) or Uint8Array (PDF, DOCX, XLSX, PPTX) depending on the format. Heavy format renderers are lazy-loaded on first use. Supports 14+ built-in formats plus custom renderers registered via `registerRenderer()`.',
|
|
75
|
+
example: `const pdf = await render(doc, 'pdf') // Uint8Array
|
|
76
|
+
const html = await render(doc, 'html') // string
|
|
77
|
+
const email = await render(doc, 'email') // Outlook-safe HTML
|
|
78
|
+
const md = await render(doc, 'md') // Markdown string
|
|
79
|
+
const slack = await render(doc, 'slack') // Slack Block Kit JSON`,
|
|
80
|
+
mistakes: [
|
|
81
|
+
'Not awaiting the render call — render() is always async due to lazy-loaded format renderers',
|
|
82
|
+
'Expecting render("pdf") to return a string — PDF, DOCX, XLSX, PPTX return Uint8Array',
|
|
83
|
+
'Passing a VNode instead of a DocNode — render() expects the output of JSX primitives (Document, Page, etc.) or createDocument(), not arbitrary Pyreon VNodes',
|
|
84
|
+
],
|
|
85
|
+
seeAlso: ['createDocument', 'Document', 'download', 'registerRenderer'],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'createDocument',
|
|
89
|
+
kind: 'function',
|
|
90
|
+
signature: '(props?: DocumentProps) => DocumentBuilder',
|
|
91
|
+
summary:
|
|
92
|
+
'Fluent builder API for constructing documents without JSX. Chain `.heading()`, `.text()`, `.table()`, `.image()`, `.list()`, `.code()`, `.divider()`, `.page()` calls. Terminal methods: `.toPdf()`, `.toDocx()`, `.toEmail()`, `.toSlack()`, `.toNotion()`, `.toHtml()`, `.toMarkdown()`, etc. Each terminal method calls `render()` internally.',
|
|
93
|
+
example: `const doc = createDocument({ title: 'Report' })
|
|
94
|
+
.heading('Sales Report')
|
|
95
|
+
.text('Q4 2026 summary.')
|
|
96
|
+
.table({ columns: ['Region', 'Revenue'], rows: [['US', '$1M']] })
|
|
97
|
+
|
|
98
|
+
await doc.toPdf() // PDF Uint8Array
|
|
99
|
+
await doc.toEmail() // Outlook-safe HTML
|
|
100
|
+
await doc.toDocx() // Word document`,
|
|
101
|
+
mistakes: [
|
|
102
|
+
'Forgetting to await terminal methods — toPdf(), toDocx(), etc. are async',
|
|
103
|
+
'Calling builder methods after a terminal method — the builder is consumed; create a new one',
|
|
104
|
+
],
|
|
105
|
+
seeAlso: ['render', 'Document'],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'Document',
|
|
109
|
+
kind: 'component',
|
|
110
|
+
signature: '(props: DocumentProps) => DocNode',
|
|
111
|
+
summary:
|
|
112
|
+
'Root JSX primitive for document trees. Accepts `title`, `author`, `subject` as metadata props. Children should be `Page` elements (or other block-level primitives for single-page documents). The returned DocNode is passed to `render()` for output.',
|
|
113
|
+
example: `const doc = (
|
|
114
|
+
<Document title="Report" author="Team">
|
|
115
|
+
<Page>
|
|
116
|
+
<Heading>Title</Heading>
|
|
117
|
+
<Text>Content</Text>
|
|
118
|
+
</Page>
|
|
119
|
+
</Document>
|
|
120
|
+
)
|
|
121
|
+
await render(doc, 'pdf')`,
|
|
122
|
+
seeAlso: ['render', 'Page', 'createDocument'],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'download',
|
|
126
|
+
kind: 'function',
|
|
127
|
+
signature: '(data: Uint8Array | string, filename: string) => void',
|
|
128
|
+
summary:
|
|
129
|
+
'Browser helper that triggers a file download from rendered document data. Creates a temporary Blob URL and clicks a hidden anchor element. Works with both Uint8Array (PDF, DOCX) and string (HTML, Markdown) outputs from `render()`.',
|
|
130
|
+
example: `const pdf = await render(doc, 'pdf')
|
|
131
|
+
download(pdf, 'report.pdf')`,
|
|
132
|
+
seeAlso: ['render'],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
gotchas: [
|
|
136
|
+
'Heavy format renderers are lazy-loaded: PDF (~300KB via pdfmake), DOCX (~100KB via docx), XLSX (~500KB via exceljs), PPTX (~200KB via pptxgenjs). First render of each format has an async import overhead; subsequent renders are instant.',
|
|
137
|
+
{
|
|
138
|
+
label: 'Format return types',
|
|
139
|
+
note: 'Binary formats (pdf, docx, xlsx, pptx) return Uint8Array. Text formats (html, email, md, text, csv, slack, teams, discord, telegram, notion, confluence, whatsapp, gchat, svg) return string.',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
label: 'JSX vs Builder',
|
|
143
|
+
note: 'Both APIs produce the same DocNode tree. JSX primitives are better for complex layouts with conditional sections. The builder API is better for programmatic generation (e.g. loop over data to build rows).',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
label: 'document-primitives',
|
|
147
|
+
note: 'For components that render in the browser AND export to documents, use `@pyreon/document-primitives` (rocketstyle-based) + `@pyreon/connector-document` — not the raw primitives from this package.',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
})
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
renderApiReferenceEntries,
|
|
3
|
+
renderLlmsFullSection,
|
|
4
|
+
renderLlmsTxtLine,
|
|
5
|
+
} from '@pyreon/manifest'
|
|
6
|
+
import manifest from '../manifest'
|
|
7
|
+
|
|
8
|
+
describe('gen-docs — document snapshot', () => {
|
|
9
|
+
it('renders to llms.txt bullet', () => {
|
|
10
|
+
expect(renderLlmsTxtLine(manifest)).toMatchInlineSnapshot(`"- @pyreon/document — Universal document rendering — 18 primitives, 14+ output formats. Heavy format renderers are lazy-loaded: PDF (~300KB via pdfmake), DOCX (~100KB via docx), XLSX (~500KB via exceljs), PPTX (~200KB via pptxgenjs). First render of each format has an async import overhead; subsequent renders are instant."`)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('renders to llms-full.txt section', () => {
|
|
14
|
+
expect(renderLlmsFullSection(manifest)).toMatchInlineSnapshot(`
|
|
15
|
+
"## @pyreon/document — Universal Document Rendering
|
|
16
|
+
|
|
17
|
+
Universal document rendering for Pyreon. One template, every output format: HTML, PDF, DOCX, XLSX, PPTX, email, Markdown, plain text, CSV, SVG, Slack, Teams, Discord, Telegram, Notion, Confluence, WhatsApp, Google Chat. Heavy renderers (PDF ~300KB, DOCX ~100KB, XLSX ~500KB, PPTX ~200KB) are lazy-loaded on demand. Supports both JSX primitives and a fluent builder API.
|
|
18
|
+
|
|
19
|
+
\`\`\`typescript
|
|
20
|
+
import { Document, Page, Heading, Text, Table, Image, List, Code, Divider, render, createDocument, download } from '@pyreon/document'
|
|
21
|
+
|
|
22
|
+
// JSX primitives — compose a document tree
|
|
23
|
+
const report = (
|
|
24
|
+
<Document title="Q4 Sales Report" author="Analytics Team">
|
|
25
|
+
<Page>
|
|
26
|
+
<Heading level={1}>Sales Report</Heading>
|
|
27
|
+
<Text>Q4 2026 performance summary.</Text>
|
|
28
|
+
<Table
|
|
29
|
+
columns={['Region', 'Revenue', 'Growth']}
|
|
30
|
+
rows={[
|
|
31
|
+
['US', '$1.2M', '+15%'],
|
|
32
|
+
['EU', '$800K', '+8%'],
|
|
33
|
+
['APAC', '$500K', '+22%'],
|
|
34
|
+
]}
|
|
35
|
+
/>
|
|
36
|
+
<Divider />
|
|
37
|
+
<Heading level={2}>Notes</Heading>
|
|
38
|
+
<List items={['Record quarter for APAC', 'EU impacted by currency exchange']} />
|
|
39
|
+
<Code language="sql">SELECT region, SUM(revenue) FROM sales GROUP BY region</Code>
|
|
40
|
+
</Page>
|
|
41
|
+
</Document>
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
// Render to any format:
|
|
45
|
+
const pdf = await render(report, 'pdf') // Uint8Array
|
|
46
|
+
const html = await render(report, 'html') // string
|
|
47
|
+
const email = await render(report, 'email') // Outlook-safe HTML
|
|
48
|
+
const docx = await render(report, 'docx') // Uint8Array
|
|
49
|
+
const xlsx = await render(report, 'xlsx') // Uint8Array
|
|
50
|
+
const md = await render(report, 'md') // Markdown string
|
|
51
|
+
const slack = await render(report, 'slack') // Slack Block Kit JSON
|
|
52
|
+
const notion = await render(report, 'notion') // Notion blocks
|
|
53
|
+
const teams = await render(report, 'teams') // Adaptive Card JSON
|
|
54
|
+
|
|
55
|
+
// Browser download helper:
|
|
56
|
+
download(pdf, 'report.pdf')
|
|
57
|
+
|
|
58
|
+
// Builder API — alternative to JSX:
|
|
59
|
+
const doc = createDocument({ title: 'Report' })
|
|
60
|
+
.heading('Sales Report')
|
|
61
|
+
.text('Q4 2026 performance summary.')
|
|
62
|
+
.table({ columns: ['Region', 'Revenue'], rows: [['US', '$1M']] })
|
|
63
|
+
|
|
64
|
+
await doc.toPdf() // PDF
|
|
65
|
+
await doc.toEmail() // email-safe HTML
|
|
66
|
+
await doc.toDocx() // Word document
|
|
67
|
+
await doc.toSlack() // Slack Block Kit
|
|
68
|
+
await doc.toNotion() // Notion blocks
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
> **Note**: Heavy format renderers are lazy-loaded: PDF (~300KB via pdfmake), DOCX (~100KB via docx), XLSX (~500KB via exceljs), PPTX (~200KB via pptxgenjs). First render of each format has an async import overhead; subsequent renders are instant.
|
|
72
|
+
>
|
|
73
|
+
> **Format return types**: Binary formats (pdf, docx, xlsx, pptx) return Uint8Array. Text formats (html, email, md, text, csv, slack, teams, discord, telegram, notion, confluence, whatsapp, gchat, svg) return string.
|
|
74
|
+
>
|
|
75
|
+
> **JSX vs Builder**: Both APIs produce the same DocNode tree. JSX primitives are better for complex layouts with conditional sections. The builder API is better for programmatic generation (e.g. loop over data to build rows).
|
|
76
|
+
>
|
|
77
|
+
> **document-primitives**: For components that render in the browser AND export to documents, use \`@pyreon/document-primitives\` (rocketstyle-based) + \`@pyreon/connector-document\` — not the raw primitives from this package.
|
|
78
|
+
"
|
|
79
|
+
`)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('renders to MCP api-reference entries', () => {
|
|
83
|
+
const record = renderApiReferenceEntries(manifest)
|
|
84
|
+
expect(Object.keys(record).length).toBe(4)
|
|
85
|
+
})
|
|
86
|
+
})
|