{"_id":"@benpley/wappler-pdfstreamer","name":"@benpley/wappler-pdfstreamer","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@benpley/wappler-pdfstreamer","version":"1.0.0","description":"Wappler extension for streaming PDF files to browser with inline display support","license":"MIT","author":{"name":"Ben Pleysier"},"keywords":["wappler","wappler-extension","pdf","pdf-viewer","pdf-stream","server-connect","inline-display","document-viewer"],"peerDependencies":{},"wappler":{"type":"extension","category":"server-connect","serverModel":["node"]},"_id":"@benpley/wappler-pdfstreamer@1.0.0","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-Fp8x2N14ayb7wwQlm1M6SJgw/Tb/7cpJ62mpblY/YLKNZWS2lKHb/EE3ummMfNllXWBp7/TjY7kKtE3Wg8pxdw==","shasum":"b270df9312b75e9dcacff80e477c7755a0f2ced9","tarball":"https://registry.npmjs.org/@benpley/wappler-pdfstreamer/-/wappler-pdfstreamer-1.0.0.tgz","fileCount":7,"unpackedSize":19968,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDeKT3EWTxT2DJpYoOoxO5z8OwqoPdpcCWKLgGI7OylEAiEA6ttHSO2t/x/HOt+cONiR1X0Z1bmt6eK8U5lroq4atRk="}]},"_npmUser":{"name":"benpley","email":"ben@pleysier.com.au"},"directories":{},"maintainers":[{"name":"benpley","email":"ben@pleysier.com.au"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/wappler-pdfstreamer_1.0.0_1762471393544_0.2539342318436657"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-06T23:23:13.429Z","1.0.0":"2025-11-06T23:23:13.746Z","modified":"2025-11-06T23:23:14.040Z"},"maintainers":[{"name":"benpley","email":"ben@pleysier.com.au"}],"description":"Wappler extension for streaming PDF files to browser with inline display support","keywords":["wappler","wappler-extension","pdf","pdf-viewer","pdf-stream","server-connect","inline-display","document-viewer"],"author":{"name":"Ben Pleysier"},"license":"MIT","readme":"# Wappler PDF Streamer Extension\n\nStream PDF files directly to the browser for inline display in your Wappler applications.\n\n## Features\n\n- ✅ Stream PDFs for inline browser display\n- ✅ Optional download mode (attachment)\n- ✅ Automatic content-type and caching headers\n- ✅ Browser caching support with ETag\n- ✅ 304 Not Modified responses for optimal performance\n- ✅ Custom display filenames\n- ✅ Comprehensive error handling\n- ✅ Supports both absolute and relative paths\n\n## Installation\n\n### 1. Install as per Wappler Extension Guidelines\n\nhttps://community.wappler.io/t/how-to-install-custom-wappler-extensions/49982\n\n### 2. Restart Wappler\n\nAfter installation, you **must restart Wappler** for it to recognize the new extension.\n\n1. Save all your work\n2. Close Wappler completely\n3. Reopen Wappler\n4. Open your project\n\n### 3. Verify Installation\n\nAfter restart, the extension should appear in Server Connect:\n\n1. Open any Server Connect file\n2. Click the \"+\" button to add a step\n3. Look for \"PDF Operations\" group\n4. You should see \"Stream PDF\" action\n\n## Quick Start\n\n### Basic Usage - Display PDF in Browser\n\nIn your Server Connect action:\n\n```json\n{\n  \"name\": \"streamPDF\",\n  \"module\": \"pdfstreamer\",\n  \"action\": \"stream\",\n  \"options\": {\n    \"filepath\": \"uploads/pdfs/document.pdf\",\n    \"disposition\": \"inline\"\n  }\n}\n```\n\n### Force Download\n\n```json\n{\n  \"name\": \"downloadPDF\",\n  \"module\": \"pdfstreamer\",\n  \"action\": \"stream\",\n  \"options\": {\n    \"filepath\": \"uploads/pdfs/document.pdf\",\n    \"filename\": \"My Document.pdf\",\n    \"disposition\": \"attachment\"\n  }\n}\n```\n\n## Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `filepath` | String | Yes | - | Path to the PDF file (relative to project root) |\n| `filename` | String | No | Original filename | Display name for the PDF |\n| `disposition` | String | No | `inline` | `inline` (display) or `attachment` (download) |\n| `cache` | Boolean | No | `true` | Enable browser caching with ETag |\n\n## Frontend Usage\n\n### Display in Browser\n\n```html\n<!-- Direct link -->\n<a href=\"/api/[server-action]/document.pdf\" target=\"_blank\" class=\"btn btn-primary\">\n  View PDF\n</a>\n\n<!-- Embed in iframe -->\n<iframe \n  src=\"/api/[server-action]/document.pdf\" \n  width=\"100%\" \n  height=\"600px\" \n  style=\"border: none;\">\n</iframe>\n```\n\n## Response Headers\n\nThe extension automatically sets optimized headers:\n\n```\nContent-Type: application/pdf\nContent-Length: [file size]\nContent-Disposition: inline; filename=\"document.pdf\"\nCache-Control: public, max-age=3600\nETag: \"[timestamp]-[size]\"\n```\n\n## Caching Behavior\n\nWhen caching is enabled (default):\n\n1. **First request**: Returns full PDF with ETag header\n2. **Subsequent requests**: Browser sends `If-None-Match` header\n3. **If unchanged**: Returns `304 Not Modified` (no data transfer)\n4. **If changed**: Returns new PDF with updated ETag\n\nCache duration: **1 hour** (3600 seconds)\n\n## Security Example\n\nAdd authentication and authorization before streaming:\n\n```json\n{\n  \"exec\": {\n    \"steps\": [\n      {\n        \"name\": \"restrict\",\n        \"module\": \"auth\",\n        \"action\": \"restrict\",\n        \"options\": {\n          \"provider\": \"security\"\n        }\n      },\n      {\n        \"name\": \"verify_ownership\",\n        \"module\": \"dbconnector\",\n        \"action\": \"single\",\n        \"options\": {\n          \"connection\": \"db\",\n          \"sql\": {\n            \"query\": \"SELECT filepath FROM pdfs WHERE id = ? AND user_id = ?\",\n            \"params\": [\"{{$_PARAM.id}}\", \"{{identity.id}}\"]\n          }\n        }\n      },\n      {\n        \"name\": \"streamPDF\",\n        \"module\": \"pdfstreamer\",\n        \"action\": \"stream\",\n        \"options\": {\n          \"filepath\": \"{{verify_ownership.filepath}}\"\n        }\n      }\n    ]\n  }\n}\n```\n\n## Path Resolution\n\nThe extension supports multiple path types:\n\n1. **Relative to project root**:\n   ```\n   \"filepath\": \"uploads/pdfs/document.pdf\"\n   // Resolves to: /your-project/uploads/pdfs/document.pdf\n   ```\n\n2. **Absolute paths**:\n   ```\n   \"filepath\": \"/var/data/pdfs/document.pdf\"\n   // Uses the path as-is\n   ```\n\n## Error Handling\n\nClear error messages for common issues:\n\n- **File not found**: `\"PDF file not found: [path]\"`\n- **Missing filepath**: `\"File path is required\"`\n- **Read error**: `\"Error reading PDF file: [error]\"`\n\n## Troubleshooting\n\n### Extension Not Showing in Wappler\n\n**Solution:** \n1. Verify the package was installed: check `node_modules/wappler-pdfstreamer`\n2. Make sure Wappler is completely closed and restarted\n3. Clear Wappler cache if needed\n\n### \"Module not found\" Error\n\n**Solution:**\n- Verify installation: `npm list wappler-pdfstreamer`\n- Reinstall if needed: `npm install wappler-pdfstreamer`\n- Restart Wappler completely\n\n### PDF Still Downloads Instead of Displaying\n\n**Solution:**\n1. Check the `disposition` parameter is set to `\"inline\"`\n2. Verify browser supports inline PDF viewing\n3. Check response headers in browser DevTools\n\n## Performance Tips\n\n1. ✅ Enable caching for static PDFs\n2. ✅ Use relative paths when possible\n3. ✅ Add authentication early in the workflow\n4. ✅ Consider CDN for frequently accessed PDFs\n\n## Advantages Over fs.download\n\n| Feature | fs.download | pdfstreamer |\n|---------|-------------|-------------|\n| Inline display | ✅ | ✅ |\n| Automatic headers | ❌ | ✅ |\n| Caching support | ❌ | ✅ |\n| ETag support | ❌ | ✅ |\n| 304 responses | ❌ | ✅ |\n| Enhanced errors | ❌ | ✅ |\n\n## Requirements\n\n- **Node.js**: >= 12.0.0\n- **Wappler**: 5.x or higher\n\n## License\n\nMIT License - see [LICENSE.md](./LICENSE.md) for details\n\n## Author\n\nBen Pleysier\n\n## Support\n\nFor issues or questions:\n- Check the troubleshooting section above\n- Visit the [Wappler Community Forum](https://community.wappler.io)\n","readmeFilename":"README.md","_rev":"1-da7dff40c19437a7de9bf19bc048a8a3"}