@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/lib/xlsx-Bb5TWyXQ.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xlsx-Bb5TWyXQ.js","names":[],"sources":["../src/renderers/xlsx.ts"],"sourcesContent":["import type {\n DocChild,\n DocNode,\n DocumentRenderer,\n RenderOptions,\n TableColumn,\n} from '../types'\n\n/**\n * XLSX renderer — lazy-loads ExcelJS on first use.\n * Extracts tables from the document and renders each as a worksheet.\n * Non-table content (headings, text) becomes header rows.\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 ExtractedSheet {\n name: string\n headings: string[]\n tables: DocNode[]\n}\n\n/** Walk the tree and group content into sheets (one per page, or one global). */\nfunction extractSheets(node: DocNode): ExtractedSheet[] {\n const sheets: ExtractedSheet[] = []\n let currentSheet: ExtractedSheet = {\n name: 'Sheet 1',\n headings: [],\n tables: [],\n }\n\n function walk(n: DocNode): void {\n switch (n.type) {\n case 'document':\n walkChildren(n)\n break\n\n case 'page':\n pushCurrentSheet()\n currentSheet = {\n name: `Sheet ${sheets.length + 1}`,\n headings: [],\n tables: [],\n }\n walkChildren(n)\n break\n\n case 'heading':\n addHeading(n)\n break\n\n case 'table':\n currentSheet.tables.push(n)\n break\n\n default:\n walkChildren(n)\n }\n }\n\n function walkChildren(n: DocNode): void {\n for (const child of n.children) {\n if (typeof child !== 'string') walk(child)\n }\n }\n\n function pushCurrentSheet(): void {\n if (currentSheet.tables.length > 0 || currentSheet.headings.length > 0) {\n sheets.push(currentSheet)\n }\n }\n\n function addHeading(n: DocNode): void {\n const text = getTextContent(n.children)\n currentSheet.headings.push(text)\n if (currentSheet.headings.length === 1) {\n currentSheet.name = text.slice(0, 31) // Excel sheet name max 31 chars\n }\n }\n\n walk(node)\n pushCurrentSheet()\n\n return sheets\n}\n\n/** Parse a cell value, handling currencies, percentages, and plain numbers. */\nfunction parseCellValue(value: string | number | undefined): string | number {\n if (value == null) return ''\n if (typeof value === 'number') return value\n\n const trimmed = value.trim()\n\n // Percentage: \"45%\" or \"12.5%\"\n if (/^-?\\d+(\\.\\d+)?%$/.test(trimmed)) {\n return Number.parseFloat(trimmed) / 100\n }\n\n // Currency: \"$1,234.56\", \"$1234\", \"-$500\"\n const currencyMatch = trimmed.match(/^-?\\$[\\d,]+(\\.\\d+)?$/)\n if (currencyMatch) {\n return Number.parseFloat(trimmed.replace(/[$,]/g, ''))\n }\n\n // Plain number: \"1,234.56\", \"1234\", \"-500.5\"\n const plainNum = Number(trimmed.replace(/,/g, ''))\n if (!Number.isNaN(plainNum) && /^-?[\\d,]+(\\.\\d+)?$/.test(trimmed)) {\n return plainNum\n }\n\n return value\n}\n\n/** Get ExcelJS number format string for a value. */\nfunction getCellFormat(\n originalValue: string | number | undefined,\n): string | undefined {\n if (typeof originalValue !== 'string') return undefined\n const trimmed = originalValue.trim()\n\n if (/^-?\\d+(\\.\\d+)?%$/.test(trimmed)) return '0.00%'\n if (/^-?\\$/.test(trimmed)) return '$#,##0.00'\n return undefined\n}\n\n/** Map alignment string to ExcelJS horizontal alignment. */\nfunction mapAlignment(align?: string): 'left' | 'center' | 'right' | undefined {\n if (align === 'left' || align === 'center' || align === 'right') return align\n return undefined\n}\n\n/** Thin border style for ExcelJS. */\nfunction thinBorder(): { style: 'thin'; color: { argb: string } } {\n return { style: 'thin', color: { argb: 'FFDDDDDD' } }\n}\n\n/** Apply header styling to a cell. */\nfunction styleHeaderCell(\n cell: {\n font: unknown\n fill: unknown\n alignment: unknown\n border: unknown\n value: unknown\n },\n col: TableColumn,\n hs: { background?: string; color?: string } | undefined,\n bordered: boolean,\n): void {\n cell.value = col.header\n cell.font = {\n bold: true,\n color: { argb: hs?.color?.replace('#', 'FF') ?? 'FF000000' },\n }\n if (hs?.background) {\n cell.fill = {\n type: 'pattern',\n pattern: 'solid',\n fgColor: { argb: hs.background.replace('#', 'FF') },\n }\n }\n cell.alignment = { horizontal: mapAlignment(col.align) ?? 'left' }\n if (bordered) {\n cell.border = {\n top: thinBorder(),\n bottom: thinBorder(),\n left: thinBorder(),\n right: thinBorder(),\n }\n }\n}\n\n/** Apply data cell value and styling. */\nfunction styleDataCell(\n cell: {\n value: unknown\n numFmt: unknown\n alignment: unknown\n fill: unknown\n border: unknown\n },\n rawValue: string | number | undefined,\n col: TableColumn,\n striped: boolean,\n isOddRow: boolean,\n bordered: boolean,\n): void {\n cell.value = parseCellValue(rawValue)\n const fmt = getCellFormat(rawValue)\n if (fmt) cell.numFmt = fmt\n cell.alignment = { horizontal: mapAlignment(col.align) ?? 'left' }\n if (striped && isOddRow) {\n cell.fill = {\n type: 'pattern',\n pattern: 'solid',\n fgColor: { argb: 'FFF9F9F9' },\n }\n }\n if (bordered) {\n cell.border = {\n top: thinBorder(),\n bottom: thinBorder(),\n left: thinBorder(),\n right: thinBorder(),\n }\n }\n}\n\n/** Render a single table node into the worksheet starting at the given row. Returns the next row number. */\nfunction renderTable(\n ws: {\n getRow: (n: number) => { getCell: (n: number) => Record<string, unknown> }\n columns: unknown[]\n },\n tableNode: DocNode,\n startRow: number,\n): number {\n let rowNum = startRow\n const columns = (\n (tableNode.props.columns ?? []) as (string | TableColumn)[]\n ).map(resolveColumn)\n const rows = (tableNode.props.rows ?? []) as (string | number)[][]\n const hs = tableNode.props.headerStyle as\n | { background?: string; color?: string }\n | undefined\n const bordered = (tableNode.props.bordered as boolean) ?? false\n\n // Caption\n if (tableNode.props.caption) {\n const captionRow = ws.getRow(rowNum)\n const captionCell = captionRow.getCell(1)\n captionCell.value = tableNode.props.caption as string\n captionCell.font = { italic: true, size: 10 }\n rowNum++\n }\n\n // Header row\n const headerRow = ws.getRow(rowNum)\n for (let i = 0; i < columns.length; i++) {\n const col = columns[i]\n if (!col) continue\n styleHeaderCell(headerRow.getCell(i + 1) as any, col, hs, bordered)\n }\n rowNum++\n\n // Data rows\n for (let r = 0; r < rows.length; r++) {\n const dataRow = ws.getRow(rowNum)\n for (let c = 0; c < columns.length; c++) {\n const col = columns[c]\n if (!col) continue\n styleDataCell(\n dataRow.getCell(c + 1) as any,\n rows[r]?.[c],\n col,\n (tableNode.props.striped as boolean) ?? false,\n r % 2 === 1,\n bordered,\n )\n }\n rowNum++\n }\n\n return rowNum + 1 // gap after table\n}\n\n/** Auto-fit column widths based on content. */\nfunction autoFitColumns(ws: {\n columns: {\n width: number\n eachCell?: (\n opts: { includeEmpty: boolean },\n cb: (cell: { value: unknown }) => void,\n ) => void\n }[]\n}): void {\n for (const col of ws.columns) {\n let maxLen = 10\n col.eachCell?.({ includeEmpty: false }, (cell) => {\n const len = String(cell.value ?? '').length\n if (len > maxLen) maxLen = len\n })\n col.width = Math.min(maxLen + 2, 50)\n }\n}\n\nexport const xlsxRenderer: DocumentRenderer = {\n async render(node: DocNode, _options?: RenderOptions): Promise<Uint8Array> {\n const ExcelJS = await import('exceljs')\n const workbook = new ExcelJS.default.Workbook()\n\n workbook.creator = (node.props.author as string) ?? ''\n workbook.title = (node.props.title as string) ?? ''\n\n const sheets = extractSheets(node)\n\n if (sheets.length === 0) {\n workbook.addWorksheet('Sheet 1')\n }\n\n for (const sheet of sheets) {\n const ws = workbook.addWorksheet(sheet.name)\n\n let rowNum = 1\n\n // Add headings as title rows\n for (const heading of sheet.headings) {\n const row = ws.getRow(rowNum)\n row.getCell(1).value = heading\n row.getCell(1).font = { bold: true, size: 14 }\n rowNum++\n }\n\n if (sheet.headings.length > 0) rowNum++ // gap after headings\n\n // Add tables\n for (const tableNode of sheet.tables) {\n rowNum = renderTable(\n ws as unknown as Parameters<typeof renderTable>[0],\n tableNode,\n rowNum,\n )\n }\n\n // Auto-fit columns (approximate)\n autoFitColumns(ws as unknown as Parameters<typeof autoFitColumns>[0])\n }\n\n const buffer = await workbook.xlsx.writeBuffer()\n return new Uint8Array(buffer as ArrayBuffer)\n },\n}\n"],"mappings":";;;;;;AAcA,SAAS,cAAc,KAAwC;AAC7D,QAAO,OAAO,QAAQ,WAAW,EAAE,QAAQ,KAAK,GAAG;;AAGrD,SAAS,eAAe,UAA8B;AACpD,QAAO,SACJ,KAAK,MACJ,OAAO,MAAM,WAAW,IAAI,eAAgB,EAAc,SAAS,CACpE,CACA,KAAK,GAAG;;;AAUb,SAAS,cAAc,MAAiC;CACtD,MAAM,SAA2B,EAAE;CACnC,IAAI,eAA+B;EACjC,MAAM;EACN,UAAU,EAAE;EACZ,QAAQ,EAAE;EACX;CAED,SAAS,KAAK,GAAkB;AAC9B,UAAQ,EAAE,MAAV;GACE,KAAK;AACH,iBAAa,EAAE;AACf;GAEF,KAAK;AACH,sBAAkB;AAClB,mBAAe;KACb,MAAM,SAAS,OAAO,SAAS;KAC/B,UAAU,EAAE;KACZ,QAAQ,EAAE;KACX;AACD,iBAAa,EAAE;AACf;GAEF,KAAK;AACH,eAAW,EAAE;AACb;GAEF,KAAK;AACH,iBAAa,OAAO,KAAK,EAAE;AAC3B;GAEF,QACE,cAAa,EAAE;;;CAIrB,SAAS,aAAa,GAAkB;AACtC,OAAK,MAAM,SAAS,EAAE,SACpB,KAAI,OAAO,UAAU,SAAU,MAAK,MAAM;;CAI9C,SAAS,mBAAyB;AAChC,MAAI,aAAa,OAAO,SAAS,KAAK,aAAa,SAAS,SAAS,EACnE,QAAO,KAAK,aAAa;;CAI7B,SAAS,WAAW,GAAkB;EACpC,MAAM,OAAO,eAAe,EAAE,SAAS;AACvC,eAAa,SAAS,KAAK,KAAK;AAChC,MAAI,aAAa,SAAS,WAAW,EACnC,cAAa,OAAO,KAAK,MAAM,GAAG,GAAG;;AAIzC,MAAK,KAAK;AACV,mBAAkB;AAElB,QAAO;;;AAIT,SAAS,eAAe,OAAqD;AAC3E,KAAI,SAAS,KAAM,QAAO;AAC1B,KAAI,OAAO,UAAU,SAAU,QAAO;CAEtC,MAAM,UAAU,MAAM,MAAM;AAG5B,KAAI,mBAAmB,KAAK,QAAQ,CAClC,QAAO,OAAO,WAAW,QAAQ,GAAG;AAKtC,KADsB,QAAQ,MAAM,uBAAuB,CAEzD,QAAO,OAAO,WAAW,QAAQ,QAAQ,SAAS,GAAG,CAAC;CAIxD,MAAM,WAAW,OAAO,QAAQ,QAAQ,MAAM,GAAG,CAAC;AAClD,KAAI,CAAC,OAAO,MAAM,SAAS,IAAI,qBAAqB,KAAK,QAAQ,CAC/D,QAAO;AAGT,QAAO;;;AAIT,SAAS,cACP,eACoB;AACpB,KAAI,OAAO,kBAAkB,SAAU,QAAO;CAC9C,MAAM,UAAU,cAAc,MAAM;AAEpC,KAAI,mBAAmB,KAAK,QAAQ,CAAE,QAAO;AAC7C,KAAI,QAAQ,KAAK,QAAQ,CAAE,QAAO;;;AAKpC,SAAS,aAAa,OAAyD;AAC7E,KAAI,UAAU,UAAU,UAAU,YAAY,UAAU,QAAS,QAAO;;;AAK1E,SAAS,aAAyD;AAChE,QAAO;EAAE,OAAO;EAAQ,OAAO,EAAE,MAAM,YAAY;EAAE;;;AAIvD,SAAS,gBACP,MAOA,KACA,IACA,UACM;AACN,MAAK,QAAQ,IAAI;AACjB,MAAK,OAAO;EACV,MAAM;EACN,OAAO,EAAE,MAAM,IAAI,OAAO,QAAQ,KAAK,KAAK,IAAI,YAAY;EAC7D;AACD,KAAI,IAAI,WACN,MAAK,OAAO;EACV,MAAM;EACN,SAAS;EACT,SAAS,EAAE,MAAM,GAAG,WAAW,QAAQ,KAAK,KAAK,EAAE;EACpD;AAEH,MAAK,YAAY,EAAE,YAAY,aAAa,IAAI,MAAM,IAAI,QAAQ;AAClE,KAAI,SACF,MAAK,SAAS;EACZ,KAAK,YAAY;EACjB,QAAQ,YAAY;EACpB,MAAM,YAAY;EAClB,OAAO,YAAY;EACpB;;;AAKL,SAAS,cACP,MAOA,UACA,KACA,SACA,UACA,UACM;AACN,MAAK,QAAQ,eAAe,SAAS;CACrC,MAAM,MAAM,cAAc,SAAS;AACnC,KAAI,IAAK,MAAK,SAAS;AACvB,MAAK,YAAY,EAAE,YAAY,aAAa,IAAI,MAAM,IAAI,QAAQ;AAClE,KAAI,WAAW,SACb,MAAK,OAAO;EACV,MAAM;EACN,SAAS;EACT,SAAS,EAAE,MAAM,YAAY;EAC9B;AAEH,KAAI,SACF,MAAK,SAAS;EACZ,KAAK,YAAY;EACjB,QAAQ,YAAY;EACpB,MAAM,YAAY;EAClB,OAAO,YAAY;EACpB;;;AAKL,SAAS,YACP,IAIA,WACA,UACQ;CACR,IAAI,SAAS;CACb,MAAM,WACH,UAAU,MAAM,WAAW,EAAE,EAC9B,IAAI,cAAc;CACpB,MAAM,OAAQ,UAAU,MAAM,QAAQ,EAAE;CACxC,MAAM,KAAK,UAAU,MAAM;CAG3B,MAAM,WAAY,UAAU,MAAM,YAAwB;AAG1D,KAAI,UAAU,MAAM,SAAS;EAE3B,MAAM,cADa,GAAG,OAAO,OAAO,CACL,QAAQ,EAAE;AACzC,cAAY,QAAQ,UAAU,MAAM;AACpC,cAAY,OAAO;GAAE,QAAQ;GAAM,MAAM;GAAI;AAC7C;;CAIF,MAAM,YAAY,GAAG,OAAO,OAAO;AACnC,MAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,MAAM,QAAQ;AACpB,MAAI,CAAC,IAAK;AACV,kBAAgB,UAAU,QAAQ,IAAI,EAAE,EAAS,KAAK,IAAI,SAAS;;AAErE;AAGA,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,MAAM,UAAU,GAAG,OAAO,OAAO;AACjC,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACvC,MAAM,MAAM,QAAQ;AACpB,OAAI,CAAC,IAAK;AACV,iBACE,QAAQ,QAAQ,IAAI,EAAE,EACtB,KAAK,KAAK,IACV,KACC,UAAU,MAAM,WAAuB,OACxC,IAAI,MAAM,GACV,SACD;;AAEH;;AAGF,QAAO,SAAS;;;AAIlB,SAAS,eAAe,IAQf;AACP,MAAK,MAAM,OAAO,GAAG,SAAS;EAC5B,IAAI,SAAS;AACb,MAAI,WAAW,EAAE,cAAc,OAAO,GAAG,SAAS;GAChD,MAAM,MAAM,OAAO,KAAK,SAAS,GAAG,CAAC;AACrC,OAAI,MAAM,OAAQ,UAAS;IAC3B;AACF,MAAI,QAAQ,KAAK,IAAI,SAAS,GAAG,GAAG;;;AAIxC,MAAa,eAAiC,EAC5C,MAAM,OAAO,MAAe,UAA+C;CAEzE,MAAM,WAAW,KADD,OAAM,OAAO,2BACA,QAAQ,UAAU;AAE/C,UAAS,UAAW,KAAK,MAAM,UAAqB;AACpD,UAAS,QAAS,KAAK,MAAM,SAAoB;CAEjD,MAAM,SAAS,cAAc,KAAK;AAElC,KAAI,OAAO,WAAW,EACpB,UAAS,aAAa,UAAU;AAGlC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,KAAK,SAAS,aAAa,MAAM,KAAK;EAE5C,IAAI,SAAS;AAGb,OAAK,MAAM,WAAW,MAAM,UAAU;GACpC,MAAM,MAAM,GAAG,OAAO,OAAO;AAC7B,OAAI,QAAQ,EAAE,CAAC,QAAQ;AACvB,OAAI,QAAQ,EAAE,CAAC,OAAO;IAAE,MAAM;IAAM,MAAM;IAAI;AAC9C;;AAGF,MAAI,MAAM,SAAS,SAAS,EAAG;AAG/B,OAAK,MAAM,aAAa,MAAM,OAC5B,UAAS,YACP,IACA,WACA,OACD;AAIH,iBAAe,GAAsD;;CAGvE,MAAM,SAAS,MAAM,SAAS,KAAK,aAAa;AAChD,QAAO,IAAI,WAAW,OAAsB;GAE/C"}
|