{"_id":"@dave_robinson/pdf-overlay","name":"@dave_robinson/pdf-overlay","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@dave_robinson/pdf-overlay","version":"0.1.0","description":"TypeScript library for placing content (text, images) on PDF files using a declarative rules-based system","author":{"name":"Dave Robinson"},"type":"module","sideEffects":false,"publishConfig":{"access":"public"},"main":"./dist/pdf-overlay.cjs","module":"./dist/pdf-overlay.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/pdf-overlay.js","require":"./dist/pdf-overlay.cjs"}},"keywords":["pdf","pdf-lib","overlay","text","image","document","typescript"],"repository":{"type":"git","url":"git+https://github.com/DaveRobinson/pdf-overlay.git"},"bugs":{"url":"https://github.com/DaveRobinson/pdf-overlay/issues"},"homepage":"https://github.com/DaveRobinson/pdf-overlay#readme","license":"MIT","engines":{"node":">=18"},"scripts":{"dev":"vite","build":"tsc && vite build","preview":"vite preview","generate-schema":"ts-json-schema-generator --path 'src/types.ts' --type 'DocumentRules' --out schema.json","test":"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","samples:generate":"npx tsx samples/generate-alignment-demo-pdf.ts && npx tsx samples/generate-styling-demo-pdf.ts && npx tsx samples/generate-pagination-demo-pdf.ts","prepublishOnly":"npm run test:run && npm run build"},"devDependencies":{"@types/node":"^24.10.1","@vitest/coverage-v8":"^4.0.14","ts-json-schema-generator":"^2.4.0","typescript":"~5.9.3","vite":"^7.2.4","vite-plugin-dts":"^4.5.4","vitest":"^4.0.14"},"dependencies":{"@pdf-lib/fontkit":"^1.1.1","pdf-lib":"^1.17.1"},"gitHead":"cde5f39db7ec698e354321e4072511a0b18fa6ec","_id":"@dave_robinson/pdf-overlay@0.1.0","_nodeVersion":"25.2.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-ZDpL5/uaatahXwJQWTCcsR+R7Cr8rzBX0LthmHPHjagqXfG6YhHrvf0TF8pCJBfv+AwNsCOpPfp2s8ibP8UhSg==","shasum":"9043c92c7a2e4b060e1f6c45edc51b64e43ee9ea","tarball":"https://registry.npmjs.org/@dave_robinson/pdf-overlay/-/pdf-overlay-0.1.0.tgz","fileCount":12,"unpackedSize":2648528,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICy6x4bzpDHb8sSbHv63lyQNXyDw0b+IljXyk/1LsgqlAiBsdmQCAdWFHz+AVNwWH0mw7bjgoBtLE+jhnzPD4U1msw=="}]},"_npmUser":{"name":"dave_robinson","email":"dave.robinson.personal@googlemail.com"},"directories":{},"maintainers":[{"name":"dave_robinson","email":"dave.robinson.personal@googlemail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pdf-overlay_0.1.0_1768554301905_0.6117531350193646"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-16T09:05:01.754Z","0.1.0":"2026-01-16T09:05:02.193Z","modified":"2026-01-16T09:05:02.434Z"},"maintainers":[{"name":"dave_robinson","email":"dave.robinson.personal@googlemail.com"}],"description":"TypeScript library for placing content (text, images) on PDF files using a declarative rules-based system","homepage":"https://github.com/DaveRobinson/pdf-overlay#readme","keywords":["pdf","pdf-lib","overlay","text","image","document","typescript"],"repository":{"type":"git","url":"git+https://github.com/DaveRobinson/pdf-overlay.git"},"author":{"name":"Dave Robinson"},"bugs":{"url":"https://github.com/DaveRobinson/pdf-overlay/issues"},"license":"MIT","readme":"# PDF Overlay\n\nThis library provides a way to add content to a PDF file by applying a structured set of rules.\n\n## Installation\n\n```bash\nnpm install @dave_robinson/pdf-overlay\n```\n\n## Usage\n\n### Node.js (File-based)\n\n```typescript\nimport { processDocumentFile } from '@dave_robinson/pdf-overlay'\nimport type { DocumentRules } from '@dave_robinson/pdf-overlay'\n\nconst rules: DocumentRules = {\n  documentMeta: {\n    fonts: {\n      body: { type: 'standard', family: 'Helvetica' },\n    },\n    defaults: {\n      fontName: 'body',\n      fontSize: 12,\n      colour: '#000000',\n    },\n  },\n  processingRules: [\n    {\n      type: 'text',\n      label: 'Header on all pages',\n      position: { x: 50, y: 750 },\n      element: { content: 'Header on all pages' },\n      page: { type: 'all' },\n    },\n    {\n      type: 'text',\n      label: 'First page footer',\n      position: { x: 50, y: 100 },\n      element: {\n        content: 'First page only',\n        colour: '#FF0000',\n      },\n      page: { type: 'first' },\n    },\n  ],\n}\n\nawait processDocumentFile('input.pdf', rules, 'output.pdf')\n```\n\n### Browser (Bytes-based)\n\n```typescript\nimport { processDocument } from '@dave_robinson/pdf-overlay'\n\nconst pdfBytes = new Uint8Array(await pdfFile.arrayBuffer())\nconst processedBytes = await processDocument(pdfBytes, rules)\n\n// Display in iframe\nconst blob = new Blob([processedBytes], { type: 'application/pdf' })\ndocument.getElementById('preview').src = URL.createObjectURL(blob)\n```\n\n### With Custom Fonts and Images\n\n```typescript\nimport { processDocumentFile } from '@dave_robinson/pdf-overlay'\n\nconst rules = {\n  documentMeta: {\n    fonts: {\n      brand: { type: 'custom', family: 'My Brand Font' }\n    }\n  },\n  processingRules: [\n    {\n      type: 'image',\n      element: { name: 'logo' },\n      position: { x: 50, y: 750 },\n      page: { type: 'all' }\n    }\n  ]\n}\n\nawait processDocumentFile('input.pdf', rules, 'output.pdf', {\n  basePaths: {\n    fonts: './assets/fonts',\n    images: './assets/images'\n  },\n  resources: {\n    fonts: { brand: 'BrandFont-Regular.ttf' },\n    images: { logo: 'company-logo.png' }\n  }\n})\n```\n\n## Key Concepts\n\n### Coordinate System\n\nPDFs use a **bottom-left origin** coordinate system:\n- Position `(0, 0)` is at the **bottom-left corner** of the page\n- X increases to the right\n- Y increases **upward** (not downward like typical screen coordinates)\n\n**Example for A4 page (595 × 842 points):**\n```typescript\n{ x: 50, y: 792 }   // Near top-left\n{ x: 50, y: 50 }    // Near bottom-left\n{ x: 545, y: 792 }  // Near top-right\n{ x: 545, y: 50 }   // Near bottom-right\n```\n\n### Units\n\nAll positions and dimensions are in **PDF points** where 1 point = 1/72 inch.\n\n**Common page sizes:**\n- A4: 595 × 842 points (210 × 297 mm)\n- US Letter: 612 × 792 points (8.5 × 11 inches)\n\n### Page Selectors\n\nTarget specific pages using page selectors:\n\n```typescript\n{ type: 'all' }                          // All pages\n{ type: 'first' }                        // First page only\n{ type: 'last' }                         // Last page only\n{ type: 'specific', pages: [1, 3, 5] }  // Pages 1, 3, and 5\n{ type: 'range', from: 2, to: 5 }       // Pages 2 through 5\n```\n\n**Negative indexing:** Use negative numbers to count from the end:\n```typescript\n{ type: 'specific', pages: [-1] }       // Last page\n{ type: 'specific', pages: [-2] }       // Second-to-last page\n```\n\n### Rule Structure\n\nEvery processing rule requires four fields:\n\n```typescript\n{\n  type: 'text',                    // 'text' or 'image'\n  page: { type: 'first' },         // PageSelector (required)\n  position: { x: 50, y: 750 },     // PositionSelector (required)\n  element: {                        // TextElement or ImageElement (required)\n    content: 'Hello'               // Element-specific properties\n  }\n}\n```\n\n## Running the Samples\n\nThe `samples/` directory contains demonstration scripts:\n\n- `text-alignment-demo.ts` - Demonstrates text alignment and bounds\n- `text-styling-demo.ts` - Demonstrates fonts, colors, and styling\n- `pagination-demo.ts` - Demonstrates all PageSelector types\n\nRun samples with [tsx](https://github.com/privatenumber/tsx):\n\n```bash\nnpx tsx samples/text-alignment-demo.ts    # Output: samples/output/text-alignment.pdf\nnpx tsx samples/text-styling-demo.ts      # Output: samples/output/text-styling.pdf\nnpx tsx samples/pagination-demo.ts        # Output: samples/output/pagination.pdf\n```\n\nTo regenerate the base PDFs (in `samples/base/`):\n\n```bash\nnpm run samples:generate\n```\n\n## Features\n\n### Currently Supported\n\n- **Text placement** with full styling (fonts, colors, opacity, line height)\n- **Text alignment** (horizontal/vertical with bounding boxes)\n- **Image placement** (PNG/JPG with positioning and sizing)\n- **Custom and standard fonts**\n- **Multiple color formats** (hex, RGB, CMYK, grayscale)\n- **Page targeting** (all, first, last, specific pages, ranges, negative indexing)\n\n### Not Currently Supported\n\nThe following pdf-lib features are not implemented in this library:\n\n- Interactive forms (text fields, checkboxes, radio buttons, dropdowns, signatures)\n- Drawing primitives (rectangles, circles, lines, shapes, SVG paths)\n- Page manipulation (adding/removing/rotating pages, merging PDFs)\n- Document metadata (title, author, subject, keywords)\n- Encryption and password protection\n- Attachments and bookmarks\n- Text rotation and transformations\n- Viewer preferences and display settings\n\n","readmeFilename":"README.md","_rev":"1-ee3bc5bf8d36474813047ff21da6267f"}