From b78f643836bc724a1b2f678df442f08ed38f7b58 Mon Sep 17 00:00:00 2001 From: krflol Date: Sat, 3 Oct 2026 06:24:43 -0500 Subject: [PATCH] Add a verified Next.js PDF download starter --- .github/workflows/nextjs.yml | 48 + README.md | 8 + examples/nextjs/.gitignore | 4 + examples/nextjs/LICENSE | 21 + examples/nextjs/README.md | 101 ++ .../nextjs/app/api/invoices/[id]/route.js | 46 + examples/nextjs/app/globals.css | 38 + examples/nextjs/app/layout.js | 11 + examples/nextjs/app/page.js | 25 + examples/nextjs/lib/invoice.mjs | 25 + examples/nextjs/next.config.mjs | 19 + examples/nextjs/package-lock.json | 1035 +++++++++++++++++ examples/nextjs/package.json | 22 + examples/nextjs/public/invoice.png | Bin 0 -> 107399 bytes examples/nextjs/templates/invoice.css | 48 + examples/nextjs/templates/invoice.html | 12 + examples/nextjs/tools/copy-public.mjs | 5 + examples/nextjs/tools/render-preview.mjs | 16 + examples/nextjs/tools/start.mjs | 7 + examples/nextjs/tools/verify.mjs | 139 +++ 20 files changed, 1630 insertions(+) create mode 100644 .github/workflows/nextjs.yml create mode 100644 examples/nextjs/.gitignore create mode 100644 examples/nextjs/LICENSE create mode 100644 examples/nextjs/README.md create mode 100644 examples/nextjs/app/api/invoices/[id]/route.js create mode 100644 examples/nextjs/app/globals.css create mode 100644 examples/nextjs/app/layout.js create mode 100644 examples/nextjs/app/page.js create mode 100644 examples/nextjs/lib/invoice.mjs create mode 100644 examples/nextjs/next.config.mjs create mode 100644 examples/nextjs/package-lock.json create mode 100644 examples/nextjs/package.json create mode 100644 examples/nextjs/public/invoice.png create mode 100644 examples/nextjs/templates/invoice.css create mode 100644 examples/nextjs/templates/invoice.html create mode 100644 examples/nextjs/tools/copy-public.mjs create mode 100644 examples/nextjs/tools/render-preview.mjs create mode 100644 examples/nextjs/tools/start.mjs create mode 100644 examples/nextjs/tools/verify.mjs diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml new file mode 100644 index 0000000..1db5b32 --- /dev/null +++ b/.github/workflows/nextjs.yml @@ -0,0 +1,48 @@ +name: Next.js PDF starter +on: + pull_request: + paths: ['examples/nextjs/**', '.github/workflows/nextjs.yml'] + push: + branches: [main] + paths: ['examples/nextjs/**', '.github/workflows/nextjs.yml'] + workflow_dispatch: +permissions: + contents: read +concurrency: + group: nextjs-${{ github.ref }} + cancel-in-progress: true +jobs: + standalone: + strategy: + fail-fast: false + matrix: + include: + - { os: ubuntu-latest, node: '22' } + - { os: ubuntu-latest, node: '24' } + - { os: windows-latest, node: '24' } + runs-on: ${{ matrix.os }} + timeout-minutes: 15 + defaults: + run: + working-directory: examples/nextjs + env: + NEXT_TELEMETRY_DISABLED: '1' + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node }} + cache: npm + cache-dependency-path: examples/nextjs/package-lock.json + - run: npm ci --ignore-scripts --no-audit --no-fund + - run: npm run preview:pdf + - run: npm run build + - run: npm run verify + - uses: actions/upload-artifact@v4 + if: always() + with: + name: nextjs-${{ matrix.os }}-${{ matrix.node }} + path: | + examples/nextjs/output/ + examples/nextjs/public/invoice.png + retention-days: 14 diff --git a/README.md b/README.md index 0bc7b0a..9525687 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,14 @@ npm run example Open `output/invoice/invoice.pdf` and `page-1.png`. The [three-page report sources](examples/report.html) demonstrate pagination, tables, and vector artwork. +## Use it in Next.js + +For a web application, start with the [Next.js PDF download example](examples/nextjs). +It includes a designed invoice, an App Router handler, production build settings +for the worker and bundled assets, and a standalone-server verification script. +The route bounds rendering and returns private PDF attachments from fictional +data; connect your own authenticated record lookup when adapting it. + ## Fonts and assets Supply file bytes explicitly. Additional fonts are registered alongside the diff --git a/examples/nextjs/.gitignore b/examples/nextjs/.gitignore new file mode 100644 index 0000000..ec3b8a6 --- /dev/null +++ b/examples/nextjs/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +.next/ +output/ +.env*.local diff --git a/examples/nextjs/LICENSE b/examples/nextjs/LICENSE new file mode 100644 index 0000000..4c99bbd --- /dev/null +++ b/examples/nextjs/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Fullbleed Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/nextjs/README.md b/examples/nextjs/README.md new file mode 100644 index 0000000..aab6ac9 --- /dev/null +++ b/examples/nextjs/README.md @@ -0,0 +1,101 @@ +# Fullbleed PDF downloads in Next.js + +A runnable App Router starter that serves a designed invoice from a Node.js +route. It includes the HTML/CSS, an actual PDF preview, and an isolated +standalone-server check. All invoice data is fictional; the public fixture +lookup is not an authentication system. + +## Run it + +Use Node.js 22 or newer. From this directory: + +```sh +npm ci --ignore-scripts +npm run build +npm start +``` + +Open `http://127.0.0.1:3000` and select **Download sample PDF**. The route +`/api/invoices/NS-1042` returns the one-page invoice as an attachment. Unknown +IDs return 404. Use `npm run dev` while editing the app. `PORT` changes the port; +`FULLBLEED_HOST` changes the production server's loopback binding. + +The lockfile pins Next.js 16.3.8, React 19.3.0 and the released Fullbleed Node +0.1.1 tarball (engine 2.5.5). Fullbleed does not yet have a configured npm +registry publisher; the dependency uses the verified GitHub release URL. +Installing this starter needs no Python, Rust, system fonts or browser renderer. + +## Adapt the document + +Edit `templates/invoice.html` and `templates/invoice.css`. The sample uses +bundled Inter, DM Serif Display and Bebas Neue. `lib/invoice.mjs` inserts an +escaped customer name from the fictional fixture. Amounts and dates are sample +content, not an invoicing ledger or tax calculation. + +After changing the template, regenerate and inspect the PDF and preview: + +```sh +npm run preview:pdf +``` + +Open `output/invoice.pdf` and `public/invoice.png`, then rebuild the app. The +checked-in image is output from Fullbleed, not a browser screenshot or mockup. + +## Keep the renderer on the server + +The route declares `runtime = 'nodejs'`. It uses filesystem reads, worker +threads and WebAssembly, so this integration needs the Node runtime. +`serverExternalPackages: ['fullbleed']` keeps Next.js from bundling the engine's +Node entrypoint. Explicit output tracing includes the worker, WASM, fonts, +WASI dependency and template files needed by the standalone server. +See Next.js's [external-package configuration](https://nextjs.org/docs/app/api-reference/config/next-config-js/serverExternalPackages) +and [standalone output documentation](https://nextjs.org/docs/app/api-reference/config/next-config-js/output). + +`npm run build` copies the public preview and browser chunks into +`.next/standalone`, after Next generates it. That folder is the deployment +artifact. Start its `server.js` with Node on a host that supports workers and +WebAssembly; set the host's normal `PORT` and `HOSTNAME` environment variables. +The local start script defaults to loopback. Hosting-provider limits and +serverless or Edge deployments have not been verified by this starter. + +## Adapt the route for real accounts + +Replace `getDemoInvoice(id)` with a session-authenticated lookup that verifies +the invoice belongs to that account **before rendering**. Keep order fields +escaped. Never accept arbitrary HTML, filesystem paths or remote asset URLs +from this public endpoint. + +The example renders at most one document at a time per server process. Extra +requests receive `503 BUSY` and `Retry-After: 2`; they do not enter an unbounded +queue. Successful PDFs have `private, no-store`, a fixed filename, a complete +content length and `nosniff`. Jobs have a 15-second rendering deadline and a +five-page cap, and receive the request's abort signal. No generated PDF is +written to application storage by the route. + +Use shared rate/usage controls for multiple processes or replicas. Measure your +host's memory and CPU before increasing capacity; each render worker can grow +to the package's 512 MiB WASM ceiling. Private document delivery also requires +your application's normal access controls, monitoring and retention policies. + +## Verify the production artifact + +After building: + +```sh +npm run verify +``` + +The check copies the standalone artifact to a fresh temporary directory outside +the app and starts it on an available loopback port. It compares a real HTTP +PDF to the direct engine output, checks headers and missing IDs, sends a +concurrent burst, then verifies recovery from actual missing-glyph and page-cap +failures. Client JavaScript is checked for accidental engine/worker inclusion. +Results and the downloaded PDF are retained under `output/`. + +Temporary artifact directories use the `fullbleed-nextjs-` prefix and are kept +for inspection. The verification script closes its own server when it finishes. +These checks cover a fictional fixture; they do not establish application +authorization, PDF standards compliance, or a hosting provider's limits. + +[Fullbleed Node API](https://github.com/fullbleed-engine/fullbleed-node) · +[Documentation](https://docs.fullbleed.dev/) · [MIT license](LICENSE) diff --git a/examples/nextjs/app/api/invoices/[id]/route.js b/examples/nextjs/app/api/invoices/[id]/route.js new file mode 100644 index 0000000..28ec29a --- /dev/null +++ b/examples/nextjs/app/api/invoices/[id]/route.js @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +import { renderPdf, FullbleedError } from 'fullbleed'; +import { getDemoInvoice, invoiceTemplate } from '../../../../lib/invoice.mjs'; + +export const runtime = 'nodejs'; +export const dynamic = 'force-dynamic'; + +// One active render per process; there is no unbounded waiting queue. +// Add authentication and a shared rate/usage limit for a deployed application. +let active = 0; +const privateHeaders = { + 'Cache-Control': 'private, no-store', + 'X-Content-Type-Options': 'nosniff', +}; +const errorResponse = (status, code, message, extra = {}) => Response.json( + { error: { code, message } }, { status, headers: { ...privateHeaders, ...extra } }, +); + +export async function GET(request, { params }) { + const { id } = await params; + const invoice = getDemoInvoice(id); + if (!invoice) return errorResponse(404, 'NOT_FOUND', 'Sample invoice not found.'); + if (active >= 1) return errorResponse(503, 'BUSY', 'A document is being prepared. Try again shortly.', { 'Retry-After': '2' }); + active++; + try { + const template = await invoiceTemplate(invoice); + const { pdf } = await renderPdf({ ...template, maxPages: 5, timeoutMs: 15_000, signal: request.signal }); + return new Response(pdf, { + headers: { + ...privateHeaders, + 'Content-Type': 'application/pdf', + 'Content-Disposition': `attachment; filename="invoice-${invoice.id}.pdf"`, + 'Content-Length': String(pdf.length), + }, + }); + } catch (error) { + const code = error instanceof FullbleedError ? error.code : 'UNEXPECTED'; + // Log an operational code only; never log customer data or document input. + console.error('Fullbleed invoice render failed:', code); + if (code === 'TIMEOUT') return errorResponse(504, code, 'Document preparation timed out.'); + if (code === 'ABORTED') return errorResponse(408, code, 'Document preparation was cancelled.'); + return errorResponse(500, 'RENDER_FAILED', 'The document could not be prepared.'); + } finally { + active--; + } +} diff --git a/examples/nextjs/app/globals.css b/examples/nextjs/app/globals.css new file mode 100644 index 0000000..04bdfa4 --- /dev/null +++ b/examples/nextjs/app/globals.css @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: MIT */ +:root { color-scheme: light; --ink: #203b32; --muted: #627169; --paper: #f7f5ee; --accent: #bb4e2c; } +* { box-sizing: border-box; } +body { margin: 0; background: var(--paper); color: var(--ink); font: 16px/1.6 system-ui, sans-serif; } +a { color: inherit; text-underline-offset: .2em; } +.nav, main, footer { max-width: 1240px; margin: auto; padding-left: 40px; padding-right: 40px; } +.nav { min-height: 104px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #cdd2c8; } +.wordmark { font-weight: 850; font-size: 30px; letter-spacing: -1.5px; text-decoration: none; } +.wordmark span { color: var(--accent); } +.eyebrow { font-size: 10px; font-weight: 750; letter-spacing: 2px; } +.hero { display: grid; grid-template-columns: 1fr .88fr; align-items: center; gap: 76px; padding: 62px 0 76px; } +h1 { font: 56px/1.06 Georgia, serif; letter-spacing: -2px; margin: 22px 0; } +h1 em { color: var(--accent); font-weight: 400; } +.lede { max-width: 430px; color: var(--muted); font-size: 17px; line-height: 1.7; margin-bottom: 30px; } +.button { display: inline-flex; justify-content: space-between; gap: 38px; align-items: center; background: var(--ink); color: white; padding: 15px 22px; font-weight: 650; text-decoration: none; } +.button:hover { background: #345949; } +a:focus-visible { outline: 3px solid var(--accent); outline-offset: 5px; } +.caption { font-size: 11px; color: var(--muted); margin-top: 13px; } +.note { border-top: 1px solid #cdd2c8; max-width: 430px; padding-top: 28px; margin-top: 45px; } +.note span, .steps article > span { font-size: 10px; font-weight: 750; letter-spacing: 1.3px; } +.note p { font-size: 13px; color: var(--muted); margin-bottom: 0; } +.paper { margin: 0; padding: 18px 18px 0; background: #dedfd3; border: 1px solid #cdd2c8; } +.paper img { display: block; width: 100%; height: auto; box-shadow: 0 7px 18px #203b3214; } +.paper figcaption { font-size: 10px; text-align: center; padding: 12px 0; color: #4b5d51; } +.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 42px; padding: 35px 0 52px; border-top: 1px solid #cdd2c8; } +.steps article > span { color: var(--accent); } +.steps h2 { font-size: 17px; line-height: 1.4; margin: 12px 0; } +.steps p { color: var(--muted); font-size: 13px; } +footer { border-top: 1px solid #cdd2c8; display: flex; gap: 28px; padding-top: 24px; padding-bottom: 28px; font-size: 11px; } +footer span { margin-right: auto; } +@media (max-width: 850px) { .hero { gap: 30px; } h1 { font-size: 43px; } } +@media (max-width: 650px) { + .nav, main, footer { padding-left: 22px; padding-right: 22px; } + .nav { min-height: 82px; } .hero { grid-template-columns: 1fr; gap: 35px; padding: 36px 0; } + h1 { font-size: 44px; } .lede { font-size: 16px; } .note { margin-top: 30px; padding-top: 20px; } + .steps { grid-template-columns: 1fr; gap: 24px; } .steps p { margin-bottom: 0; } + footer { flex-wrap: wrap; gap: 14px 25px; } footer span { width: 100%; } +} diff --git a/examples/nextjs/app/layout.js b/examples/nextjs/app/layout.js new file mode 100644 index 0000000..4e3b2d8 --- /dev/null +++ b/examples/nextjs/app/layout.js @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import './globals.css'; + +export const metadata = { + title: 'A better PDF download | Fullbleed + Next.js', + description: 'A runnable Next.js starter serving a designed invoice with Fullbleed. Fictional sample data.', +}; + +export default function Layout({ children }) { + return {children}; +} diff --git a/examples/nextjs/app/page.js b/examples/nextjs/app/page.js new file mode 100644 index 0000000..06c6c33 --- /dev/null +++ b/examples/nextjs/app/page.js @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +export default function Page() { + return <> +
fullbleed.NEXT.JS STARTER
+
+
+
+

A SMALL ROUTE. A BETTER DOCUMENT.

+

Make the download
worth opening.

+

Serve a designed PDF from your Next.js app. Start with this studio invoice, then make the HTML and CSS your own.

+ Download sample PDF +

One page · Fictional invoice NS-1042 · No sign-in

+
YOUR APP. YOUR DOCUMENTS.

The PDF is generated on your Node.js server with bundled fonts. Your HTML and CSS define the printed page.

+
+
Actual Fullbleed PDF: a Northstar Studio invoice with cream paper, green tables, oversized type and an orange accent.
Actual PDF output · Northstar Studio
+
+
+
01 / DESIGN

Keep your HTML & CSS.

Edit the included template. Use the bundled typefaces or supply your own font files.

+
02 / CONNECT

Use your application data.

The sample route looks up a fictional invoice. Connect your own authorized record lookup when adapting it.

+
03 / DELIVER

Send a real PDF.

A normal download link calls the server route. Rendering has a page limit, deadline and capacity limit.

+
+
+ + ; +} diff --git a/examples/nextjs/lib/invoice.mjs b/examples/nextjs/lib/invoice.mjs new file mode 100644 index 0000000..b112f39 --- /dev/null +++ b/examples/nextjs/lib/invoice.mjs @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +// Fictional public fixture, not an authorization implementation. In your app, +// replace this with an authenticated lookup scoped to the requesting account. +const invoices = new Map([ + ['NS-1042', { id: 'NS-1042', customer: 'Maple & Finch' }], +]); + +export function getDemoInvoice(id) { + return invoices.get(id); +} + +const escapeHtml = value => String(value).replace(/[&<>"']/g, char => ({ + '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', +})[char]); + +export async function invoiceTemplate(invoice) { + const [html, css] = await Promise.all([ + readFile(join(process.cwd(), 'templates/invoice.html'), 'utf8'), + readFile(join(process.cwd(), 'templates/invoice.css'), 'utf8'), + ]); + return { html: html.replace('{{customer}}', () => escapeHtml(invoice.customer)), css }; +} diff --git a/examples/nextjs/next.config.mjs b/examples/nextjs/next.config.mjs new file mode 100644 index 0000000..5cfa072 --- /dev/null +++ b/examples/nextjs/next.config.mjs @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +import { fileURLToPath } from 'node:url'; + +const root = fileURLToPath(new URL('.', import.meta.url)); + +export default { + output: 'standalone', + poweredByHeader: false, + serverExternalPackages: ['fullbleed'], + outputFileTracingRoot: root, + turbopack: { root }, + outputFileTracingIncludes: { + '/api/invoices/*': [ + './templates/**/*', + './node_modules/fullbleed/**/*', + './node_modules/@bjorn3/browser_wasi_shim/**/*', + ], + }, +}; diff --git a/examples/nextjs/package-lock.json b/examples/nextjs/package-lock.json new file mode 100644 index 0000000..02fcffa --- /dev/null +++ b/examples/nextjs/package-lock.json @@ -0,0 +1,1035 @@ +{ + "name": "fullbleed-nextjs-starter", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fullbleed-nextjs-starter", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "fullbleed": "https://github.com/fullbleed-engine/fullbleed-node/releases/download/v0.1.1/fullbleed-0.1.1.tgz", + "next": "16.3.8", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@bjorn3/browser_wasi_shim": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@bjorn3/browser_wasi_shim/-/browser_wasi_shim-0.4.2.tgz", + "integrity": "sha512-/iHkCVUG3VbcbmEHn5iIUpIrh7a7WPiwZ3sHy4HZKZzBdSadwdddYDZAII2zBvQYV0Lfi8naZngPCN7WPHI/hA==", + "license": "MIT OR Apache-2.0" + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz", + "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz", + "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.4" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz", + "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz", + "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz", + "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz", + "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz", + "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz", + "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz", + "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz", + "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz", + "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz", + "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz", + "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz", + "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz", + "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz", + "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz", + "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz", + "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz", + "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz", + "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz", + "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz", + "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz", + "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz", + "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz", + "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz", + "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@next/env": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.8.tgz", + "integrity": "sha512-Al9zqHVV7TJv0eFuOU4U7Lvv74PTih4Ch63sk2xCIpSTkE3udFnaOcnzP2lQVymiL7yS9Cj2iClUXlR3EQ5sEw==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.8.tgz", + "integrity": "sha512-2JPRMh2nmQG5CiL7cXGL9AGwnPWJQ//cTtAUCT+w511QHk79SYz3LGv/pc5X643B/WEO0rvu3Yww0hqwt3kgeA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.8.tgz", + "integrity": "sha512-GZtCCOBKJ4leVIT/Th0llWKhD1ca92lzbQiS5R5ON9QkoiFnilFsebDae1JU2a3HWoKMEmEZWGs1AGLavVM72Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.8.tgz", + "integrity": "sha512-O659ygeQYqneJ1fBKMpFxIFqYkYswu8IAS1OCKK/4f3ZgJJm1dRz4fVJZRi/kLLWjnBKnebOePA4WNv+sV1pVA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.8.tgz", + "integrity": "sha512-dSjKSyWpzxoO1d3DIZZcP4XJcNaKeLmxQMFOiYl5vuBRMmweIqnAhty8tAmRsvTss779cK1FtYnDMj40e4TQlg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.8.tgz", + "integrity": "sha512-lbqOuz3RPRcv+o9msNsJw5x4+Y1ZwPTs6vmL6DCf7i0fZfvng/F59wyeDwqHIvV0mK//RBy/jJkZ+nCKsSMXjQ==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.8.tgz", + "integrity": "sha512-+316WswI8ScVgZeUd+1KGaXkHhaYQzCjvH/05TZSpJ8zBizb1a4G7DtO7F12jcBIqMOtsz9ji1t48fmKtzqsGA==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.8.tgz", + "integrity": "sha512-ji0gd4kMYUxO+1fJBIbiBVRCjzG/lloiyCccnlebvb1ZJ5qXCPZqYg4Jl1DrrixnWNMKylzgpmMWx0yNDYXlzw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.8.tgz", + "integrity": "sha512-WcTlaKt/TWkh5kUjdJcUmB1XgZ+1c6fz4Y9fDHL73YNSdGaUWjceeWrrlwF0nv19iABYWC4iAq1oX1w4Bn0vfg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.27.tgz", + "integrity": "sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001814", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001814.tgz", + "integrity": "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/fullbleed": { + "version": "0.1.1", + "resolved": "https://github.com/fullbleed-engine/fullbleed-node/releases/download/v0.1.1/fullbleed-0.1.1.tgz", + "integrity": "sha512-kWVXlLp0ZYlXRcaiOg0GMJyM8ll0+1R1dV5LokzaoBZwzsNZ2Lz84g5ZH0/PvIN3kFd5An4ZvwGKn5VUR00TtA==", + "license": "MIT", + "dependencies": { + "@bjorn3/browser_wasi_shim": "0.4.2" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "16.3.8", + "resolved": "https://registry.npmjs.org/next/-/next-16.3.8.tgz", + "integrity": "sha512-U7QEZaTini6wKrb8A8hqLLqYQyCetegKjCpJOyxk642vWoMoU1x5PyZCJFvgYgiptA8xc5j/9xYlZFO7w9Sjmw==", + "license": "MIT", + "dependencies": { + "@next/env": "16.3.8", + "@swc/helpers": "0.5.23", + "baseline-browser-mapping": "^2.9.19", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.5.23", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.3.8", + "@next/swc-darwin-x64": "16.3.8", + "@next/swc-linux-arm64-gnu": "16.3.8", + "@next/swc-linux-arm64-musl": "16.3.8", + "@next/swc-linux-x64-gnu": "16.3.8", + "@next/swc-linux-x64-musl": "16.3.8", + "@next/swc-win32-arm64-msvc": "16.3.8", + "@next/swc-win32-x64-msvc": "16.3.8", + "sharp": "^0.35.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz", + "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.5", + "@img/sharp-darwin-x64": "0.35.5", + "@img/sharp-freebsd-wasm32": "0.35.5", + "@img/sharp-libvips-darwin-arm64": "1.3.4", + "@img/sharp-libvips-darwin-x64": "1.3.4", + "@img/sharp-libvips-linux-arm": "1.3.4", + "@img/sharp-libvips-linux-arm64": "1.3.4", + "@img/sharp-libvips-linux-ppc64": "1.3.4", + "@img/sharp-libvips-linux-riscv64": "1.3.4", + "@img/sharp-libvips-linux-s390x": "1.3.4", + "@img/sharp-libvips-linux-x64": "1.3.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", + "@img/sharp-libvips-linuxmusl-x64": "1.3.4", + "@img/sharp-linux-arm": "0.35.5", + "@img/sharp-linux-arm64": "0.35.5", + "@img/sharp-linux-ppc64": "0.35.5", + "@img/sharp-linux-riscv64": "0.35.5", + "@img/sharp-linux-s390x": "0.35.5", + "@img/sharp-linux-x64": "0.35.5", + "@img/sharp-linuxmusl-arm64": "0.35.5", + "@img/sharp-linuxmusl-x64": "0.35.5", + "@img/sharp-webcontainers-wasm32": "0.35.5", + "@img/sharp-win32-arm64": "0.35.5", + "@img/sharp-win32-ia32": "0.35.5", + "@img/sharp-win32-x64": "0.35.5" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + } + } +} diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json new file mode 100644 index 0000000..238786c --- /dev/null +++ b/examples/nextjs/package.json @@ -0,0 +1,22 @@ +{ + "name": "fullbleed-nextjs-starter", + "version": "1.0.0", + "private": true, + "type": "module", + "license": "MIT", + "engines": { "node": ">=22" }, + "scripts": { + "dev": "next dev --hostname 127.0.0.1", + "build": "next build", + "postbuild": "node tools/copy-public.mjs", + "start": "node tools/start.mjs", + "preview:pdf": "node tools/render-preview.mjs", + "verify": "node tools/verify.mjs" + }, + "dependencies": { + "fullbleed": "https://github.com/fullbleed-engine/fullbleed-node/releases/download/v0.1.1/fullbleed-0.1.1.tgz", + "next": "16.3.8", + "react": "19.3.0", + "react-dom": "19.3.0" + } +} diff --git a/examples/nextjs/public/invoice.png b/examples/nextjs/public/invoice.png new file mode 100644 index 0000000000000000000000000000000000000000..82d648ff2da4bc639aee1790b80bc5843e58ff42 GIT binary patch literal 107399 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 literal 0 HcmV?d00001 diff --git a/examples/nextjs/templates/invoice.css b/examples/nextjs/templates/invoice.css new file mode 100644 index 0000000..235023f --- /dev/null +++ b/examples/nextjs/templates/invoice.css @@ -0,0 +1,48 @@ +@page { size: A4; margin: 0; } +* { box-sizing: border-box; } +html, body { margin: 0; padding: 0; } +body { font-family: Inter; font-size: 10pt; line-height: 1.45; color: #17382e; } +h1, h2, h3, p, figure { margin: 0; } +h1, h2, h3 { font-weight: 400; } +.page { width: 210mm; height: 296.9mm; padding: 15mm 16mm; position: relative; break-after: page; background: #f8f5ec; } +.page:last-child { break-after: auto; } +.kicker { font-size: 7.2pt; font-weight: 600; letter-spacing: 1.4pt; text-transform: uppercase; } +.serif { font-family: 'DM Serif Display'; font-weight: 400; } +.display { font-family: 'Bebas Neue'; font-weight: 400; } +.muted { color: #5b6c64; } +.small { font-size: 8pt; } +.rule { border-top: .6pt solid #9eafa4; } +.row { display: flex; justify-content: space-between; gap: 16pt; } +.grid-2 { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 24pt; } +.grid-2 > * { min-width: 0; } +.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16pt; } +.footer { position: absolute; left: 16mm; right: 16mm; bottom: 12mm; border-top: .6pt solid #9eafa4; padding-top: 8pt; display: flex; justify-content: space-between; gap: 12pt; font-size: 6.6pt; letter-spacing: .45pt; } +table { width: 100%; border-collapse: collapse; font-size: 9pt; } +th { font-size: 7.5pt; font-weight: 600; text-align: left; } +th, td { padding: 10pt 0; border-bottom: .55pt solid #bdc8bf; vertical-align: top; } +.number { text-align: right; white-space: nowrap; } +.money { font-variant-numeric: tabular-nums; } +strong { font-weight: 600; } +a { color: inherit; } + +.invoice .masthead { display: grid; grid-template-columns: 1.05fr .8fr 1fr; gap: 18pt; align-items: center; padding-bottom: 22pt; border-bottom: 1pt solid #17382e; } +.invoice .brand { font: 31pt/.88 'DM Serif Display'; letter-spacing: -1.3pt; } +.invoice .brand span { display: block; line-height: .98; } +.invoice .brand small { display: block; font: 6.5pt Inter; letter-spacing: 2.1pt; margin-top: 11pt; } +.invoice .brand-note { border-left: 1pt solid #c24929; padding: 4pt 0 4pt 16pt; line-height: 1.8; } +.invoice .address { font-size: 7.5pt; line-height: 1.7; border-left: 1pt solid #c24929; padding-left: 16pt; } +.invoice .title-row { display: grid; grid-template-columns: 3.3fr 1fr; gap: 20pt; align-items: center; padding: 22pt 0 16pt; } +.invoice h1 { font: 91pt/.9 'Bebas Neue'; letter-spacing: .3pt; } +.invoice .title-note { color: #b44123; font: 14pt/1.2 'Bebas Neue'; letter-spacing: .5pt; } +.invoice .details { border-top: .6pt solid #9eafa4; border-bottom: .6pt solid #9eafa4; padding: 15pt 0; margin-bottom: 10pt; } +.invoice .details p { margin-top: 5pt; font-size: 8.2pt; } +.invoice .details > div + div { border-left: .6pt solid #c7cdc4; padding-left: 14pt; } +.invoice th { color: #52665a; } +.invoice td { padding: 12pt 0; } +.invoice .item-note { color: #617069; font-size: 8pt; margin-top: 4pt; } +.invoice .amounts { display: grid; grid-template-columns: 1fr 1.25fr; gap: 27pt; margin-top: 23pt; } +.invoice .thanks { font: italic 22pt/1.2 'DM Serif Display'; color: #b44123; padding-top: 8pt; } +.invoice .summary-line { display: flex; justify-content: space-between; padding: 5pt 0; font-size: 8.5pt; } +.invoice .total { background: #17382e; color: #fff8e8; padding: 16pt; margin-top: 9pt; border-left: 4pt solid #d96238; } +.invoice .total .value { font: 38pt/1.1 'Bebas Neue'; margin-top: 7pt; } +.invoice .payment { margin-top: 20pt; padding-top: 12pt; border-top: .6pt solid #9eafa4; display: grid; grid-template-columns: 1fr 1fr; gap: 24pt; font-size: 8pt; } diff --git a/examples/nextjs/templates/invoice.html b/examples/nextjs/templates/invoice.html new file mode 100644 index 0000000..bb0d7e9 --- /dev/null +++ b/examples/nextjs/templates/invoice.html @@ -0,0 +1,12 @@ +Northstar Studio — Invoice NS-1042 +
+
NorthstarStudioDESIGN WITH DIRECTION
Brand
Digital
Experiences
That matter.
42 Cedar Avenue
Portland, OR 97205
hello@example.invalid
northstar.example.invalid
+

INVOICE

GOOD WORK.
CLEAR DETAILS.
LET'S MAKE
WHAT'S NEXT.

+

Prepared for

{{customer}}
Attn. Avery Morgan
Portland, Oregon

The project

Autumn launch
Brand workshop, digital
design & handoff

Invoice NS-1042

Issued · 01 October 2026
Due · 31 October 2026
Currency · USD

+ + +
DESCRIPTIONHOURSRATEAMOUNT
Discovery & brand workshop

Positioning, priorities, and a clear creative direction

8$125.00$1,000.00
Digital design & implementation

A cohesive visual system, from layout to launch

6$95.00$570.00
Review & studio handoff

Final refinements, documentation, and delivery

2$150.00$300.00
+

A little clarity.
A lot of possibility.

Thank you for inviting us
to help shape your next chapter.

Subtotal$1,870.00
Tax · 0% in this sample$0.00
TOTAL DUE · USD
$1,870.00
+

Payment details

Reference NS-1042 with your payment.
Payment instructions are supplied separately.

A note from the studio

Questions about a line item?
Write to hello@example.invalid.

+
NORTHSTAR STUDIO / INVOICE NS-1042FICTIONAL SAMPLE · 01 / 01
+
diff --git a/examples/nextjs/tools/copy-public.mjs b/examples/nextjs/tools/copy-public.mjs new file mode 100644 index 0000000..3fa2158 --- /dev/null +++ b/examples/nextjs/tools/copy-public.mjs @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT +import { cp } from 'node:fs/promises'; +// Next's standalone output does not copy public files or browser chunks itself. +await cp('public', '.next/standalone/public', { recursive: true }); +await cp('.next/static', '.next/standalone/.next/static', { recursive: true }); diff --git a/examples/nextjs/tools/render-preview.mjs b/examples/nextjs/tools/render-preview.mjs new file mode 100644 index 0000000..d203792 --- /dev/null +++ b/examples/nextjs/tools/render-preview.mjs @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +import { mkdir, writeFile } from 'node:fs/promises'; +import { createHash } from 'node:crypto'; +import { renderPdf, version } from 'fullbleed'; +import { getDemoInvoice, invoiceTemplate } from '../lib/invoice.mjs'; + +const result = await renderPdf({ ...await invoiceTemplate(getDemoInvoice('NS-1042')), previewDpi: 96, maxPages: 5, timeoutMs: 15_000 }); +if (result.pages !== 1 || result.missingGlyphs !== 0) throw new Error('Review the sample layout before publishing.'); +await mkdir('public', { recursive: true }); +await mkdir('output', { recursive: true }); +await writeFile('public/invoice.png', result.previews[0]); +await writeFile('output/invoice.pdf', result.pdf); +const hash = value => createHash('sha256').update(value).digest('hex'); +const record = { nodePackage: version, engineVersion: result.engineVersion, pages: result.pages, missingGlyphs: result.missingGlyphs, pdfSha256: hash(result.pdf), previewSha256: hash(result.previews[0]) }; +await writeFile('output/preview.json', JSON.stringify(record, null, 2) + '\n'); +console.log(JSON.stringify(record)); diff --git a/examples/nextjs/tools/start.mjs b/examples/nextjs/tools/start.mjs new file mode 100644 index 0000000..59b410f --- /dev/null +++ b/examples/nextjs/tools/start.mjs @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; + +process.env.HOSTNAME = process.env.FULLBLEED_HOST || '127.0.0.1'; +process.env.NODE_ENV = 'production'; +await import(pathToFileURL(resolve('.next/standalone/server.js')).href); diff --git a/examples/nextjs/tools/verify.mjs b/examples/nextjs/tools/verify.mjs new file mode 100644 index 0000000..3ca0671 --- /dev/null +++ b/examples/nextjs/tools/verify.mjs @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: MIT +// Exercise the production artifact with fictional data, outside the source tree. +import assert from 'node:assert/strict'; +import { spawn } from 'node:child_process'; +import { createHash } from 'node:crypto'; +import { cp, mkdir, mkdtemp, readFile, readdir, writeFile } from 'node:fs/promises'; +import { createServer } from 'node:net'; +import { tmpdir, platform } from 'node:os'; +import { join, resolve } from 'node:path'; +import { setTimeout as delay } from 'node:timers/promises'; +import { renderPdf, version, engineVersion } from 'fullbleed'; +import { getDemoInvoice, invoiceTemplate } from '../lib/invoice.mjs'; + +const checks = []; +const check = (name, condition) => { assert.ok(condition, name); checks.push({ name, passed: true }); console.log(`${name}: passed`); }; +const hash = data => createHash('sha256').update(data).digest('hex'); +const project = process.cwd(); +const folder = await mkdtemp(join(tmpdir(), 'fullbleed-nextjs-')); +await mkdir('output', { recursive: true }); +await cp('.next/standalone', folder, { recursive: true, dereference: true }); +await cp('public', join(folder, 'public'), { recursive: true }); +await cp('.next/static', join(folder, '.next/static'), { recursive: true }); +check('standalone artifact is isolated from the source application', !resolve(folder).startsWith(resolve(project))); +const manifest = JSON.parse(await readFile(join(folder, 'node_modules/fullbleed/dist/build.json'), 'utf8')); +for (const [name, expected] of Object.entries(manifest.files)) { + const bytes = await readFile(join(folder, 'node_modules/fullbleed', name)); + assert.equal(hash(bytes), expected.sha256, name); +} +check('standalone tracing retains the verified engine and all bundled fonts', manifest.engineVersion === engineVersion); + +const socket = createServer(); +await new Promise(done => socket.listen(0, '127.0.0.1', done)); +const port = socket.address().port; +await new Promise(done => socket.close(done)); +const base = `http://127.0.0.1:${port}`; +const child = spawn(process.execPath, ['server.js'], { cwd: folder, windowsHide: true, env: { ...process.env, NODE_ENV: 'production', NEXT_TELEMETRY_DISABLED: '1', HOSTNAME: '127.0.0.1', PORT: String(port) }, stdio: ['ignore', 'pipe', 'pipe'] }); +let logs = ''; +for (const stream of [child.stdout, child.stderr]) stream.on('data', data => { logs = (logs + data.toString()).slice(-50000); }); +const stopped = new Promise((done, reject) => { child.once('error', reject); child.once('close', (code, signal) => done({ code, signal })); }); +stopped.catch(() => {}); +const stop = async () => { if (child.exitCode === null && child.signalCode === null) child.kill(); await stopped; }; +const get = (path, options = {}) => fetch(base + path, { ...options, signal: AbortSignal.timeout(25000) }); +let serving = false; +try { + let ready = false; + for (let attempt = 0; attempt < 120; attempt++) { + if (child.exitCode !== null) throw new Error(`Standalone server stopped.\n${logs}`); + try { ready = (await get('/')).status === 200; } catch {} + if (ready) break; + await delay(250); + } + check('isolated production server starts on loopback', ready); + const html = await (await get('/')).text(); + check('app exposes the sample download without a prefetched render', html.includes('Download sample PDF') && html.includes('href="/api/invoices/NS-1042"') && !html.includes('rel="prefetch"')); + const image = await get('/invoice.png'); + check('standalone server includes the actual PDF preview asset', image.status === 200 && hash(Buffer.from(await image.arrayBuffer())) === hash(await readFile('public/invoice.png'))); + const expected = await renderPdf({ ...await invoiceTemplate(getDemoInvoice('NS-1042')), maxPages: 5, timeoutMs: 15000 }); + const url = '/api/invoices/NS-1042'; + async function pdfResponse(response) { + const bytes = Buffer.from(await response.arrayBuffer()); + assert.equal(response.status, 200); + assert.equal(response.headers.get('content-type'), 'application/pdf'); + assert.equal(response.headers.get('content-disposition'), 'attachment; filename="invoice-NS-1042.pdf"'); + assert.equal(response.headers.get('content-length'), String(bytes.length)); + assert.match(response.headers.get('cache-control'), /private.*no-store/); + assert.equal(response.headers.get('x-content-type-options'), 'nosniff'); + assert.equal(hash(bytes), hash(expected.pdf)); + return bytes; + } + const bytes = await pdfResponse(await get(url)); + await writeFile('output/route.pdf', bytes); + check('production route returns complete private PDF bytes with a useful filename', true); + const missing = await get('/api/invoices/NS-9999'); + check('unknown invoice IDs return a private JSON error', missing.status === 404 && /no-store/.test(missing.headers.get('cache-control')) && (await missing.json()).error.code === 'NOT_FOUND'); + check('unsupported writes are rejected by the route', (await get(url, { method: 'POST', body: '{}' })).status === 405); + + const burst = await Promise.all(Array.from({ length: 12 }, async () => { + const response = await get(url); + if (response.status === 200) { await pdfResponse(response); return 200; } + assert.equal(response.status, 503); + assert.equal(response.headers.get('retry-after'), '2'); + assert.match(response.headers.get('cache-control'), /no-store/); + assert.equal((await response.json()).error.code, 'BUSY'); + return 503; + })); + check('a concurrent burst receives explicit capacity errors instead of an unbounded queue', burst.includes(200) && burst.includes(503)); + await pdfResponse(await get(url)); + check('normal PDF downloads recover after a capacity burst', true); + + const templatePath = join(folder, 'templates/invoice.html'); + const original = await readFile(templatePath); + try { + await writeFile(templatePath, '

Integral: \u2a0c

'); + const failure = await get(url); + const body = await failure.json(); + check('a real missing-glyph failure returns a generic non-PDF error', failure.status === 500 && body.error.code === 'RENDER_FAILED' && !JSON.stringify(body).includes('Integral')); + } finally { await writeFile(templatePath, original); } + await pdfResponse(await get(url)); + check('a valid document renders after an engine failure', true); + try { + await writeFile(templatePath, '

Page limit sample

'.repeat(7)); + const failure = await get(url); + check('the route enforces its page cap against a real multipage document', failure.status === 500 && (await failure.json()).error.code === 'RENDER_FAILED' && logs.includes('PAGE_LIMIT')); + } finally { await writeFile(templatePath, original); } + await pdfResponse(await get(url)); + check('a valid document renders after the page limit rejects a job', true); + + async function jsFiles(directory) { + const result = []; + for (const entry of await readdir(directory, { withFileTypes: true })) { + const path = join(directory, entry.name); + if (entry.isDirectory()) result.push(...await jsFiles(path)); + else if (entry.name.endsWith('.js')) result.push(path); + } + return result; + } + const chunks = await jsFiles(join(folder, '.next/static')); + for (const file of chunks) assert.doesNotMatch(await readFile(file, 'utf8'), /browser_wasi_shim|engine\.wasm|node:worker_threads/); + check('client JavaScript excludes the server PDF engine and worker', chunks.length > 0); + const info = JSON.parse(await readFile('package.json', 'utf8')); + const record = { checkedAt: new Date().toISOString(), node: process.version, platform: platform(), next: info.dependencies.next, nodePackage: version, engineVersion, + packageLockSha256: hash(await readFile('package-lock.json')), base, standaloneFolder: folder, pages: expected.pages, pdfSha256: hash(bytes), burst, checks, + scope: 'Real next build standalone server with released Fullbleed tarball and fictional data. No hosted platform or application-authentication claim.' }; + await writeFile('output/verification.json', JSON.stringify(record, null, 2) + '\n'); + await writeFile('output/server.log', logs); + if (process.argv.includes('--serve')) { + serving = true; + console.log(`FULLBLEED_NEXT_PREVIEW_READY ${base}`); + process.once('SIGINT', async () => { await stop(); process.exit(0); }); + process.once('SIGTERM', async () => { await stop(); process.exit(0); }); + await stopped; + } +} catch (error) { + await writeFile('output/failure.json', JSON.stringify({ error: error.stack, checks, base, standaloneFolder: folder }, null, 2) + '\n'); + await writeFile('output/server.log', logs); + throw error; +} finally { + if (!serving) await stop(); +}