@pyreon/document 0.10.0 → 0.11.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.
Files changed (76) hide show
  1. package/lib/analysis/index.js.html +1 -1
  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/{dist-BsqdI2nY.js → dist-CYL41kqQ.js} +2 -2
  6. package/lib/dist-CYL41kqQ.js.map +1 -0
  7. package/lib/{docx-BEBOihjl.js → docx-uNAel545.js} +7 -2
  8. package/lib/docx-uNAel545.js.map +1 -0
  9. package/lib/email-D0bbfWq4.js.map +1 -1
  10. package/lib/{exceljs-BoIDUUaw.js → exceljs-BYETsesT.js} +314 -314
  11. package/lib/exceljs-BYETsesT.js.map +1 -0
  12. package/lib/google-chat-CkKCBUWC.js.map +1 -1
  13. package/lib/html-B5biprN2.js.map +1 -1
  14. package/lib/index.js +17 -8
  15. package/lib/index.js.map +1 -1
  16. package/lib/markdown-CdtlFGC0.js.map +1 -1
  17. package/lib/notion-iG2C5bEY.js.map +1 -1
  18. package/lib/{pdf-DIUQUEdj.js → pdf-IuBgTb3T.js} +9 -3
  19. package/lib/pdf-IuBgTb3T.js.map +1 -0
  20. package/lib/{pdfmake-DnmLxK4Q.js → pdfmake-CKMX5URW.js} +2 -4
  21. package/lib/pdfmake-CKMX5URW.js.map +1 -0
  22. package/lib/{pptx-Dd33oL3_.js → pptx-DXiMiYFM.js} +7 -2
  23. package/lib/pptx-DXiMiYFM.js.map +1 -0
  24. package/lib/{pptxgen.es-COcgXsyx.js → pptxgen.es-FsqHs8mD.js} +3 -6
  25. package/lib/pptxgen.es-FsqHs8mD.js.map +1 -0
  26. package/lib/sanitize-O_3j1mNJ.js.map +1 -1
  27. package/lib/slack-BI3EQwYm.js.map +1 -1
  28. package/lib/svg-BKxumy-p.js.map +1 -1
  29. package/lib/teams-Cwz9lce0.js.map +1 -1
  30. package/lib/telegram-gYFqyMXb.js.map +1 -1
  31. package/lib/text-l1XNXBOC.js.map +1 -1
  32. package/lib/types/index.d.ts +43 -39
  33. package/lib/types/index.d.ts.map +1 -1
  34. package/lib/{vfs_fonts-Df1kkZ4Y.js → vfs_fonts-Cap07Jg3.js} +2 -2
  35. package/lib/vfs_fonts-Cap07Jg3.js.map +1 -0
  36. package/lib/whatsapp-CjSGoOKx.js.map +1 -1
  37. package/lib/{xlsx-Bb5TWyXQ.js → xlsx-Cvu4LBNy.js} +8 -2
  38. package/lib/xlsx-Cvu4LBNy.js.map +1 -0
  39. package/package.json +19 -7
  40. package/src/builder.ts +53 -44
  41. package/src/download.ts +32 -36
  42. package/src/env.d.ts +3 -17
  43. package/src/index.ts +6 -8
  44. package/src/nodes.ts +45 -45
  45. package/src/render.ts +45 -118
  46. package/src/renderers/confluence.ts +64 -80
  47. package/src/renderers/csv.ts +11 -18
  48. package/src/renderers/discord.ts +38 -50
  49. package/src/renderers/docx.ts +78 -120
  50. package/src/renderers/email.ts +73 -92
  51. package/src/renderers/google-chat.ts +35 -47
  52. package/src/renderers/html.ts +78 -101
  53. package/src/renderers/markdown.ts +43 -53
  54. package/src/renderers/notion.ts +63 -85
  55. package/src/renderers/pdf.ts +92 -115
  56. package/src/renderers/pptx.ts +60 -66
  57. package/src/renderers/slack.ts +49 -61
  58. package/src/renderers/svg.ts +49 -63
  59. package/src/renderers/teams.ts +68 -80
  60. package/src/renderers/telegram.ts +40 -54
  61. package/src/renderers/text.ts +44 -66
  62. package/src/renderers/whatsapp.ts +34 -48
  63. package/src/renderers/xlsx.ts +47 -61
  64. package/src/sanitize.ts +21 -25
  65. package/src/tests/document.test.ts +1337 -1385
  66. package/src/tests/stress.test.ts +111 -111
  67. package/src/types.ts +66 -65
  68. package/lib/dist-BsqdI2nY.js.map +0 -1
  69. package/lib/docx-BEBOihjl.js.map +0 -1
  70. package/lib/exceljs-BoIDUUaw.js.map +0 -1
  71. package/lib/pdf-DIUQUEdj.js.map +0 -1
  72. package/lib/pdfmake-DnmLxK4Q.js.map +0 -1
  73. package/lib/pptx-Dd33oL3_.js.map +0 -1
  74. package/lib/pptxgen.es-COcgXsyx.js.map +0 -1
  75. package/lib/vfs_fonts-Df1kkZ4Y.js.map +0 -1
  76. package/lib/xlsx-Bb5TWyXQ.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"pdf-DIUQUEdj.js","names":[],"sources":["../src/renderers/pdf.ts"],"sourcesContent":["import type {\n DocChild,\n DocNode,\n DocumentRenderer,\n RenderOptions,\n TableColumn,\n} from '../types'\n\n/**\n * PDF renderer — lazy-loads pdfmake on first use.\n * pdfmake handles pagination, tables, text wrapping, and font embedding.\n *\n * @example\n * ```ts\n * import { render, Document, Page, Heading } from '@pyreon/document'\n *\n * const doc = Document({\n * title: 'Report',\n * children: Page({ children: Heading({ children: 'Hello' }) }),\n * })\n * const pdf = await render(doc, 'pdf') // → Uint8Array\n * ```\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\ntype PdfContent = Record<string, unknown> | string | PdfContent[]\n\n/** pdfmake expects page sizes as `{ width, height }` objects. */\nconst PAGE_SIZES: Record<string, { width: number; height: number }> = {\n A3: { width: 841.89, height: 1190.55 },\n A4: { width: 595.28, height: 841.89 },\n A5: { width: 419.53, height: 595.28 },\n letter: { width: 612, height: 792 },\n legal: { width: 612, height: 1008 },\n tabloid: { width: 792, height: 1224 },\n}\n\n/**\n * Resolve an image `src` for pdfmake.\n *\n * - `data:` URIs are passed through directly (pdfmake supports base64).\n * - `http(s)://` URLs cannot be resolved at render time in the browser.\n * A placeholder text node is returned instead.\n * - Relative / absolute paths (e.g. `/logo.png`) cannot be resolved without\n * a server-side fetch, so they are skipped with a placeholder.\n */\nfunction resolveImageSrc(\n src: string,\n): { image: string } | { text: string; italics: true; color: string } {\n if (src.startsWith('data:')) {\n return { image: src }\n }\n if (src.startsWith('http://') || src.startsWith('https://')) {\n return { text: `[Image: ${src}]`, italics: true, color: '#999999' }\n }\n // Local path — cannot resolve in browser\n return { text: `[Image: ${src}]`, italics: true, color: '#999999' }\n}\n\nfunction nodeToContent(node: DocNode): PdfContent | PdfContent[] | null {\n const p = node.props\n\n switch (node.type) {\n case 'document':\n case 'page':\n return node.children\n .map((c) => (typeof c === 'string' ? c : nodeToContent(c)))\n .filter((c): c is PdfContent => c != null)\n\n case 'section': {\n const content = node.children\n .map((c) => (typeof c === 'string' ? c : nodeToContent(c)))\n .filter((c): c is PdfContent => c != null)\n .flat()\n\n if (p.direction === 'row') {\n return {\n columns: node.children\n .filter((c): c is DocNode => typeof c !== 'string')\n .map((child) => ({\n stack: [nodeToContent(child)].flat().filter(Boolean),\n width:\n child.props.width === '*' || !child.props.width\n ? '*'\n : child.props.width,\n })),\n columnGap: (p.gap as number) ?? 0,\n }\n }\n\n return content\n }\n\n case 'row': {\n return {\n columns: node.children\n .filter((c): c is DocNode => typeof c !== 'string')\n .map((child) => ({\n stack: [nodeToContent(child)].flat().filter(Boolean),\n width: child.props.width ?? '*',\n })),\n columnGap: (p.gap as number) ?? 0,\n }\n }\n\n case 'column':\n return node.children\n .map((c) => (typeof c === 'string' ? c : nodeToContent(c)))\n .filter((c): c is PdfContent => c != null)\n .flat()\n\n case 'heading': {\n const level = (p.level as number) ?? 1\n const sizes: Record<number, number> = {\n 1: 24,\n 2: 20,\n 3: 18,\n 4: 16,\n 5: 14,\n 6: 12,\n }\n return {\n text: getTextContent(node.children),\n fontSize: sizes[level] ?? 18,\n bold: true,\n color: (p.color as string) ?? '#000000',\n alignment: (p.align as string) ?? 'left',\n margin: [0, level === 1 ? 0 : 8, 0, 8],\n }\n }\n\n case 'text':\n return {\n text: getTextContent(node.children),\n fontSize: (p.size as number) ?? 12,\n color: (p.color as string) ?? '#333333',\n bold: p.bold ?? false,\n italics: p.italic ?? false,\n decoration: p.underline\n ? 'underline'\n : p.strikethrough\n ? 'lineThrough'\n : undefined,\n alignment: (p.align as string) ?? 'left',\n lineHeight: (p.lineHeight as number) ?? 1.4,\n margin: [0, 0, 0, 8],\n }\n\n case 'link':\n return {\n text: getTextContent(node.children),\n link: p.href as string,\n color: (p.color as string) ?? '#4f46e5',\n decoration: 'underline',\n }\n\n case 'image': {\n const src = p.src as string\n const resolved = resolveImageSrc(src)\n\n if ('image' in resolved) {\n const result: Record<string, unknown> = {\n image: resolved.image,\n fit: [p.width ?? 500, p.height ?? 400],\n margin: [0, 0, 0, 8],\n }\n if (p.align === 'center') result.alignment = 'center'\n if (p.align === 'right') result.alignment = 'right'\n return result\n }\n\n // Placeholder for non-resolvable images\n return { ...resolved, margin: [0, 0, 0, 8] }\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 const hs = p.headerStyle as\n | { background?: string; color?: string }\n | undefined\n\n const headerRow = columns.map((col) => ({\n text: col.header,\n bold: true,\n fillColor: hs?.background ?? '#f5f5f5',\n color: hs?.color ?? '#000000',\n alignment: col.align ?? 'left',\n }))\n\n const dataRows = rows.map((row, rowIdx) =>\n columns.map((col, colIdx) => ({\n text: String(row[colIdx] ?? ''),\n alignment: col.align ?? 'left',\n fillColor: p.striped && rowIdx % 2 === 1 ? '#f9f9f9' : undefined,\n })),\n )\n\n const widths = columns.map((col) => {\n if (!col.width) return '*'\n if (typeof col.width === 'string' && col.width.endsWith('%')) {\n return col.width\n }\n return col.width\n })\n\n return {\n table: {\n headerRows: 1,\n widths,\n body: [headerRow, ...dataRows],\n },\n layout: p.bordered ? undefined : 'lightHorizontalLines',\n unbreakable: p.keepTogether ?? false,\n margin: [0, 0, 0, 12],\n }\n }\n\n case 'list': {\n const items = node.children\n .filter((c): c is DocNode => typeof c !== 'string')\n .map((item) => getTextContent(item.children))\n\n return p.ordered\n ? { ol: items, margin: [0, 0, 0, 8] }\n : { ul: items, margin: [0, 0, 0, 8] }\n }\n\n case 'list-item':\n return getTextContent(node.children)\n\n case 'code':\n return {\n text: getTextContent(node.children),\n font: 'Courier',\n fontSize: 10,\n background: '#f5f5f5',\n margin: [0, 0, 0, 8],\n }\n\n case 'page-break':\n return { text: '', pageBreak: 'after' }\n\n case 'divider':\n return {\n canvas: [\n {\n type: 'line',\n x1: 0,\n y1: 0,\n x2: 515,\n y2: 0,\n lineWidth: (p.thickness as number) ?? 1,\n lineColor: (p.color as string) ?? '#dddddd',\n },\n ],\n margin: [0, 8, 0, 8],\n }\n\n case 'spacer':\n return { text: '', margin: [0, (p.height as number) ?? 12, 0, 0] }\n\n case 'button':\n return {\n text: getTextContent(node.children),\n link: p.href as string,\n bold: true,\n color: (p.color as string) ?? '#ffffff',\n background: (p.background as string) ?? '#4f46e5',\n margin: [0, 8, 0, 8],\n }\n\n case 'quote':\n return {\n table: {\n widths: [4, '*'],\n body: [\n [\n { text: '', fillColor: (p.borderColor as string) ?? '#dddddd' },\n {\n text: getTextContent(node.children),\n italics: true,\n color: '#555555',\n margin: [8, 4, 0, 4],\n },\n ],\n ],\n },\n layout: 'noBorders',\n margin: [0, 4, 0, 8],\n }\n\n default:\n return null\n }\n}\n\nfunction resolveMargin(\n margin:\n | number\n | [number, number]\n | [number, number, number, number]\n | undefined,\n): [number, number, number, number] {\n if (margin == null) return [40, 40, 40, 40]\n if (typeof margin === 'number') return [margin, margin, margin, margin]\n if (margin.length === 2) return [margin[1], margin[0], margin[1], margin[0]]\n return margin\n}\n\n/**\n * Render header/footer DocNodes into pdfmake content for page headers/footers.\n *\n * pdfmake header/footer functions receive `(currentPage, pageCount, pageSize)`\n * and must return a content object. We flatten the DocNode into static content.\n */\nfunction renderHeaderFooter(node: DocNode | undefined): PdfContent | undefined {\n if (!node) return undefined\n const content = nodeToContent(node)\n if (content == null) return undefined\n if (Array.isArray(content)) return { stack: content, margin: [40, 10, 40, 0] }\n if (typeof content === 'object')\n return { ...content, margin: [40, 10, 40, 0] }\n return { text: content, margin: [40, 10, 40, 0] }\n}\n\nexport const pdfRenderer: DocumentRenderer = {\n async render(node: DocNode, _options?: RenderOptions): Promise<Uint8Array> {\n // Lazy-load pdfmake — handle ESM/CJS interop\n const pdfMakeModule = await import('pdfmake/build/pdfmake')\n const pdfFontsModule = await import('pdfmake/build/vfs_fonts')\n\n // Resolve the actual exports (handle .default for ESM wrappers).\n // pdfmake's default export is a singleton instance of browser_extensions_pdfmake.\n // ESM interop may wrap it in an extra .default layer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- pdfmake types are incomplete\n let pdfMake: any = pdfMakeModule.default ?? pdfMakeModule\n if (pdfMake.default && typeof pdfMake.default.createPdf === 'function') {\n pdfMake = pdfMake.default\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- pdfmake types are incomplete\n const pdfFonts: any = pdfFontsModule.default ?? pdfFontsModule\n\n // Assign virtual filesystem for fonts\n if (pdfMake.vfs == null) {\n pdfMake.vfs = pdfFonts.pdfMake?.vfs ?? pdfFonts.vfs\n }\n\n // Find page config\n const pageNode = node.children.find(\n (c): c is DocNode => typeof c !== 'string' && c.type === 'page',\n )\n const pageSize = (pageNode?.props.size as string) ?? 'A4'\n const pageOrientation =\n (pageNode?.props.orientation as string) ?? 'portrait'\n const pageMargin = resolveMargin(\n pageNode?.props.margin as\n | number\n | [number, number]\n | [number, number, number, number]\n | undefined,\n )\n\n const content = [nodeToContent(node)].flat().filter(Boolean) as PdfContent[]\n\n // Build header/footer from PageProps if present\n const headerFn = renderHeaderFooter(\n pageNode?.props.header as DocNode | undefined,\n )\n const footerFn = renderHeaderFooter(\n pageNode?.props.footer as DocNode | undefined,\n )\n\n const docDefinition: Record<string, unknown> = {\n pageSize: PAGE_SIZES[pageSize] ?? PAGE_SIZES.A4,\n pageOrientation,\n pageMargins: pageMargin,\n info: {\n title: (node.props.title as string) ?? '',\n author: (node.props.author as string) ?? '',\n subject: (node.props.subject as string) ?? '',\n keywords: (node.props.keywords as string[])?.join(', ') ?? '',\n },\n content,\n defaultStyle: {\n fontSize: 12,\n lineHeight: 1.4,\n },\n // Keep sections together — break before a heading if it would be\n // orphaned at the bottom of a page.\n pageBreakBefore: (\n currentNode: { headlineLevel?: number },\n helpers: { getFollowingNodesOnPage?: () => unknown[] },\n ) => {\n if (currentNode.headlineLevel && helpers.getFollowingNodesOnPage) {\n const following = helpers.getFollowingNodesOnPage()\n if (following.length === 0) return true\n }\n return false\n },\n }\n\n if (headerFn) docDefinition.header = headerFn\n if (footerFn) docDefinition.footer = footerFn\n\n try {\n const pdf = pdfMake.createPdf(docDefinition)\n const buffer = await pdf.getBuffer()\n return new Uint8Array(buffer)\n } catch (err) {\n throw new Error(`[@pyreon/document] PDF generation failed: ${err}`)\n }\n },\n}\n"],"mappings":"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"}