{"_id":"@edvizion/pdfs","_rev":"2-1ef6e57bad0bf682b3915d57135f30c9","name":"@edvizion/pdfs","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@edvizion/pdfs","version":"0.1.0","_id":"@edvizion/pdfs@0.1.0","maintainers":[{"name":"kvizdos","email":"kvizdos@gmail.com"}],"dist":{"shasum":"9deef3917d0e07dfda035f9fe2124d7e01f7d388","tarball":"https://registry.npmjs.org/@edvizion/pdfs/-/pdfs-0.1.0.tgz","fileCount":22,"integrity":"sha512-bWeTnyFK8vUMw/+aXVHtEkBQCtQBmMGEkN1MNgG4UmfO6QFgIcClB6U+qcelmfChm55RGhiOGJxpwIPKZiI8Eg==","signatures":[{"sig":"MEQCIAX9OqvCzQQpsNe5OyB/pD4HSWDvqhE8VobgiKA2jHFtAiAaRu9vdCq9v4RsuUes6NQC7Nycg5mHIl2kX1ug4ztriA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50742},"type":"module","exports":{".":{"types":"./dist/http/index.d.ts","import":"./dist/http/index.js","default":"./dist/http/index.js"},"./binding":{"types":"./dist/binding/index.d.ts","import":"./dist/binding/index.js","default":"./dist/binding/index.js"},"./contract":{"types":"./dist/contract/index.d.ts","import":"./dist/contract/index.js","default":"./dist/contract/index.js"}},"gitHead":"3d20102fd8b9b7e10a2aab62ed5f4ef7c5812ea6","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"kvizdos","email":"kvizdos@gmail.com"},"_npmVersion":"11.11.0","description":"SDK and shared contract for the edvizion-pdfs service.","directories":{},"_nodeVersion":"25.8.1","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"~4.1.0","typescript":"^5.5.2","@types/node":"^26.2.0"},"_npmOperationalInternal":{"tmp":"tmp/pdfs_0.1.0_1787344311367_0.6560493376926051","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@edvizion/pdfs","version":"0.1.1","type":"module","description":"SDK and shared contract for the edvizion-pdfs service.","license":"UNLICENSED","publishConfig":{"access":"public"},"exports":{".":{"types":"./dist/http/index.d.ts","import":"./dist/http/index.js","default":"./dist/http/index.js"},"./binding":{"types":"./dist/binding/index.d.ts","import":"./dist/binding/index.js","default":"./dist/binding/index.js"},"./contract":{"types":"./dist/contract/index.d.ts","import":"./dist/contract/index.js","default":"./dist/contract/index.js"}},"scripts":{"build":"rm -rf dist && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit","test":"vitest run"},"dependencies":{"zod":"^4.4.3"},"devDependencies":{"@types/node":"^26.2.0","typescript":"^5.5.2","vitest":"~4.1.0"},"gitHead":"d718f245755e03d2b719390f6c49c97165e7541c","_id":"@edvizion/pdfs@0.1.1","_nodeVersion":"25.8.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-I4idWUmwCEdavrQyFO5UaANGV7Xel+jX+D0J1TP/4I2IBzGRyxLKiylY2uzYA+cjnx/RkK/w+fyrjH8qMxvnPg==","shasum":"57e8c02a0c8f63c87dfc16b352468a8f8909b4ab","tarball":"https://registry.npmjs.org/@edvizion/pdfs/-/pdfs-0.1.1.tgz","fileCount":21,"unpackedSize":54691,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIB+Xm3CsfRAG3Wr6M0oYtbjArPuMGMfkmSCLwjJz3n+iAiEAg/JS0bnxKOhJCNlqXlzf0mdMAhtZUHpElNmKBsDU+28="}]},"_npmUser":{"name":"kvizdos","email":"kvizdos@gmail.com"},"directories":{},"maintainers":[{"name":"kvizdos","email":"kvizdos@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pdfs_0.1.1_1787344694567_0.11222842918741316"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-21T20:31:51.109Z","modified":"2026-08-21T20:38:14.986Z","0.1.0":"2026-08-21T20:31:51.492Z","0.1.1":"2026-08-21T20:38:14.709Z"},"description":"SDK and shared contract for the edvizion-pdfs service.","maintainers":[{"name":"kvizdos","email":"kvizdos@gmail.com"}],"readme":"# @edvizion/pdfs\n\nTypeScript SDK and shared contract for **edvizion-pdfs**, Edvizion's PDF\ntemplate rendering service.\n\n> **This package is internal.** It is published to the public npm registry for\n> convenience of installation, not for general use. It is a client for a\n> private Cloudflare Worker that is not publicly reachable — without access to\n> Edvizion's infrastructure, this package cannot do anything useful.\n>\n> There is no public API, no hosted demo, and no support for outside use.\n\n## What it is\n\nThe service stores per-organization PDF templates and renders them into PDFs.\nThis package is the client for it, over either transport:\n\n- **Service binding** — Worker-to-Worker RPC. Trusted caller, no JWT.\n- **HTTP** — Bearer JWT, for callers outside the Cloudflare account.\n\nBoth expose the same methods, the same arguments, and the same error classes.\nMoving a caller between transports is an import change.\n\nIt also carries the **contract**: the zod schemas, TypeScript types, and error\ncodes that the service itself validates against. Those are defined once and\nshared, so the client and the service cannot disagree about a payload shape\nwithout a compile error.\n\n## Access requirements\n\n| Transport | Requires |\n| --- | --- |\n| `@edvizion/pdfs/binding` | a Worker in the same Cloudflare account as `edvizion-pdfs` |\n| `@edvizion/pdfs` (HTTP) | an AuthKit access token carrying an `org_id` claim and the right scope |\n\nService bindings are account-scoped, so the binding transport is unavailable\noutside Edvizion's account. The HTTP endpoint is deployed but every route\nexcept `/health` and `/openapi.json` requires a verified token.\n\n## Install\n\n```bash\nnpm i @edvizion/pdfs\n```\n\n## Quick start\n\nService binding — add to the calling Worker's `wrangler.jsonc`:\n\n```jsonc\n\"services\": [\n  { \"binding\": \"PDFS\", \"service\": \"edvizion-pdfs\", \"entrypoint\": \"PDFService\" }\n]\n```\n\n```ts\nimport { pdfs } from \"@edvizion/pdfs/binding\";\n\nconst client = pdfs(env.PDFS, { tenantID: org.id, userID: user.id });\n\nconst bytes = await client.generate({\n  templateID: \"tpl_standard_record_request\",\n  type: \"record-request\",\n  payload,\n});\n```\n\nHTTP:\n\n```ts\nimport { PDFClient } from \"@edvizion/pdfs\";\n\nconst client = new PDFClient({\n  baseURL: \"https://api.edvizion.com/pdf\",\n  token: () => getAccessToken(),\n});\n\nconst bytes = await client.generate({ templateID, type: \"record-request\", payload });\n```\n\n`entrypoint: \"PDFService\"` is required on the binding — omitting it binds the\nJWT-protected HTTP handler instead, and every call fails on auth.\n\n## Exports\n\n| Import | Contents | Runs in |\n| --- | --- | --- |\n| `@edvizion/pdfs` | `PDFClient` — HTTP transport | Workers, Node, browser |\n| `@edvizion/pdfs/binding` | `pdfs()`, `PDFBindingClient`, `PDFServiceBinding` | Workers only |\n| `@edvizion/pdfs/contract` | types, zod schemas, error classes, `PDFServiceContract` | anywhere |\n\nThe contract is re-exported from both transport entry points, so importing it\nseparately is only necessary when you want types without a client.\n\n## Documentation\n\n**[SKILL.md](./SKILL.md)** ships with this package and is the complete\nintegration guide: setup, every method, payload contracts, the error table,\nLiquid template authoring, and testing guidance. It is written to be handed\ndirectly to a coding agent — drop it at\n`.claude/skills/edvizion-pdfs/SKILL.md` in the consuming repo.\n\n## Errors\n\nBoth transports throw the same typed errors, rebuilt from a shared error code:\n\n```ts\nimport { TemplateNotFoundError, InvalidTemplatePayloadError } from \"@edvizion/pdfs/contract\";\n\ntry {\n  await client.generate({ templateID, payload });\n} catch (error) {\n  if (error instanceof InvalidTemplatePayloadError) return badRequest(error.issues);\n  if (error instanceof TemplateNotFoundError) return notFound();\n  throw error;\n}\n```\n\nCross-tenant access returns `template_not_found`, never a permission error — a\nresponse must never reveal that another organization's template exists.\n\n## Testing against it\n\nThe service is fully unit tested on its own. Consuming apps should test their\nown logic, not re-verify the service's rules. The binding is a plain structural\ninterface with no Cloudflare types, so stubbing it needs nothing but an object\nliteral:\n\n```ts\nconst stub = { generate: vi.fn(), /* … */ } satisfies PDFServiceBinding;\nconst client = pdfs(stub, { tenantID: \"org_a\", userID: \"user_a\" });\n```\n\nA stub will accept calls the real service rejects. That is expected — a unit\ntest against a double is not an integration test. See SKILL.md.\n\n## Versioning\n\nThis package and the deployed Worker share the contract, so they are released\ntogether. Adding a template type is additive and safe to roll out in either\norder. **Changing an existing payload schema is breaking** — tightening a field\nrejects payloads that previously worked — and requires publishing the SDK and\ndeploying the Worker in lockstep.\n\n## License\n\nUNLICENSED — proprietary to Edvizion. Published publicly for installation\nconvenience; no rights are granted for outside use.\n","readmeFilename":"README.md","license":"UNLICENSED"}