{"_id":"@davecthomas/ai-api-unified-http-client","_rev":"4-35d6d49d5205e9453568f7722e6fb813","name":"@davecthomas/ai-api-unified-http-client","dist-tags":{"latest":"1.6.0"},"versions":{"1.0.0":{"name":"@davecthomas/ai-api-unified-http-client","version":"1.0.0","license":"MIT","_id":"@davecthomas/ai-api-unified-http-client@1.0.0","maintainers":[{"name":"davecthomas","email":"davecthomas@duck.com"}],"homepage":"https://github.com/davecthomas/ai-api-unified-http#readme","bugs":{"url":"https://github.com/davecthomas/ai-api-unified-http/issues"},"dist":{"shasum":"f23884eae5f2d2a1a71195fe41facbbd4f87311e","tarball":"https://registry.npmjs.org/@davecthomas/ai-api-unified-http-client/-/ai-api-unified-http-client-1.0.0.tgz","fileCount":11,"integrity":"sha512-uar8f9Hyl1XsgbEMbU+bDBAW6h3aOvy1LvCcNBj/47tHsJcr0wR+DIqjZG3uKLn0St6sc8lzo9UXntsKzebj4A==","signatures":[{"sig":"MEYCIQCsWfnzij94N1bDfdu66+GPuGPvMkQDXYkKUD6EVikKvgIhAMxadH79yp1DaMlpTDR0UL1yahz6xIrnJFsp6d4rRdoS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113359},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"5612b3867e8075e76fde09746ad166ab500d7358","scripts":{"build":"tsc","smoke":"npm run build && node --experimental-strip-types smoke.ts","generate":"openapi-typescript ./openapi.json -o ./src/schema.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"davecthomas","email":"davecthomas@duck.com"},"repository":{"url":"git+https://github.com/davecthomas/ai-api-unified-http.git","type":"git","directory":"clients/typescript"},"_npmVersion":"11.11.1","description":"Typed TypeScript client for ai-api-unified-http, generated from its OpenAPI spec.","directories":{},"_nodeVersion":"22.9.0","dependencies":{"openapi-fetch":"^0.13.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","openapi-typescript":"^7.4.0"},"_npmOperationalInternal":{"tmp":"tmp/ai-api-unified-http-client_1.0.0_1786312586912_0.8642995227024979","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@davecthomas/ai-api-unified-http-client","version":"1.1.0","license":"MIT","_id":"@davecthomas/ai-api-unified-http-client@1.1.0","maintainers":[{"name":"davecthomas","email":"davecthomas@duck.com"}],"homepage":"https://github.com/davecthomas/ai-api-unified-http#readme","bugs":{"url":"https://github.com/davecthomas/ai-api-unified-http/issues"},"dist":{"shasum":"72d2f5142d1ba156be9851bc007f001b1fca20ba","tarball":"https://registry.npmjs.org/@davecthomas/ai-api-unified-http-client/-/ai-api-unified-http-client-1.1.0.tgz","fileCount":11,"integrity":"sha512-WHtkaxqA3v4eYONfhIYYdNqtW6+rTlOpRkQ3lB0qZF0ETvZsWuWR8xL/58fSHQn+4UP1K6iy1Z/yEUvCrgrGiQ==","signatures":[{"sig":"MEYCIQDHeBwWmyPjc8uIN3uprFojqe1pUP3fCisbhAXw5+GcgAIhAIg/gIGDarozFqxlrjEFAD5HwO36QbwQeaFRwhkeVkqB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@davecthomas%2fai-api-unified-http-client@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":116962},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d154a74ea17a47b2309c69da59d4ce891f16ba9d","scripts":{"build":"tsc","smoke":"npm run build && node --experimental-strip-types smoke.ts","generate":"openapi-typescript ./openapi.json -o ./src/schema.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f4be2b35-7b0c-481d-b03c-866e9835864e"}},"repository":{"url":"git+https://github.com/davecthomas/ai-api-unified-http.git","type":"git","directory":"clients/typescript"},"_npmVersion":"12.0.2","description":"Typed TypeScript client for ai-api-unified-http, generated from its OpenAPI spec.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.13.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","openapi-typescript":"^7.4.0"},"_npmOperationalInternal":{"tmp":"tmp/ai-api-unified-http-client_1.1.0_1786401482039_0.4439495206201052","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@davecthomas/ai-api-unified-http-client","version":"1.2.0","license":"MIT","_id":"@davecthomas/ai-api-unified-http-client@1.2.0","maintainers":[{"name":"davecthomas","email":"davecthomas@duck.com"}],"homepage":"https://github.com/davecthomas/ai-api-unified-http#readme","bugs":{"url":"https://github.com/davecthomas/ai-api-unified-http/issues"},"dist":{"shasum":"eff961a895f80126523ee13989eebca09848d38e","tarball":"https://registry.npmjs.org/@davecthomas/ai-api-unified-http-client/-/ai-api-unified-http-client-1.2.0.tgz","fileCount":11,"integrity":"sha512-kppX7FdQJryOAlnL5eQ8VCthLp48qKxLvTqdSNv2hyh+y2E/u0PfHUPVPykIvF+hF9YQ9O/hl/AjiKqDMc5jZw==","signatures":[{"sig":"MEUCIQD1JV/cswlJf3hQkHZHQABxgDnsQQN/MkSbBSIXGd0mYQIgEvCviWzchlIv6m0CQKmJS0AVASZPGR+eRSJSRCt17rc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@davecthomas%2fai-api-unified-http-client@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":161397},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"814a452f2970bc1402823bdd7faf3c9406cdcd2d","scripts":{"build":"tsc","smoke":"npm run build && node --experimental-strip-types smoke.ts","generate":"openapi-typescript ./openapi.json -o ./src/schema.ts","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f4be2b35-7b0c-481d-b03c-866e9835864e"}},"repository":{"url":"git+https://github.com/davecthomas/ai-api-unified-http.git","type":"git","directory":"clients/typescript"},"_npmVersion":"12.0.2","description":"Typed TypeScript client for ai-api-unified-http, generated from its OpenAPI spec.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"openapi-fetch":"^0.13.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","openapi-typescript":"^7.4.0"},"_npmOperationalInternal":{"tmp":"tmp/ai-api-unified-http-client_1.2.0_1786401532201_0.1229093503105787","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@davecthomas/ai-api-unified-http-client","version":"1.6.0","description":"Typed TypeScript client for ai-api-unified-http, generated from its OpenAPI spec.","license":"MIT","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"repository":{"type":"git","url":"git+https://github.com/davecthomas/ai-api-unified-http.git","directory":"clients/typescript"},"scripts":{"build":"tsc","generate":"openapi-typescript ./openapi.json -o ./src/schema.ts","typecheck":"tsc --noEmit","smoke":"npm run build && node --experimental-strip-types smoke.ts","prepublishOnly":"npm run build"},"dependencies":{"openapi-fetch":"^0.13.0"},"devDependencies":{"openapi-typescript":"^7.4.0","typescript":"^5.6.0"},"publishConfig":{"access":"public"},"gitHead":"a27c60fbaf7d99664bc3458acc32bafadae879dc","_id":"@davecthomas/ai-api-unified-http-client@1.6.0","bugs":{"url":"https://github.com/davecthomas/ai-api-unified-http/issues"},"homepage":"https://github.com/davecthomas/ai-api-unified-http#readme","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-SU2b7RMqRwdopYHtb7ra5F1j27tLKlk39j6ukFy+p4LDzbxa5UhTkD9ZmclvO0/uwhHjjVZIggBTfDnMY/Cadw==","shasum":"f4bcdc15767d4819358060a190f93f05c60b4174","tarball":"https://registry.npmjs.org/@davecthomas/ai-api-unified-http-client/-/ai-api-unified-http-client-1.6.0.tgz","fileCount":11,"unpackedSize":249407,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@davecthomas%2fai-api-unified-http-client@1.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBdPlfs7yBRm6IQlyQP1tGx4aoGvgQugKGcBRCKhsVMUAiEAz2H3El5AodGUaPptymgYaUuFSBtGRMxHXnOCnQT7g/A="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f4be2b35-7b0c-481d-b03c-866e9835864e"}},"directories":{},"maintainers":[{"name":"davecthomas","email":"davecthomas@duck.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ai-api-unified-http-client_1.6.0_1786917551903_0.051638900515285746"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-09T21:56:26.673Z","modified":"2026-08-16T21:59:12.321Z","1.0.0":"2026-08-09T21:56:27.055Z","1.1.0":"2026-08-10T22:38:02.214Z","1.2.0":"2026-08-10T22:38:52.324Z","1.6.0":"2026-08-16T21:59:12.044Z"},"bugs":{"url":"https://github.com/davecthomas/ai-api-unified-http/issues"},"license":"MIT","homepage":"https://github.com/davecthomas/ai-api-unified-http#readme","repository":{"type":"git","url":"git+https://github.com/davecthomas/ai-api-unified-http.git","directory":"clients/typescript"},"description":"Typed TypeScript client for ai-api-unified-http, generated from its OpenAPI spec.","maintainers":[{"name":"davecthomas","email":"davecthomas@duck.com"}],"readme":"# @davecthomas/ai-api-unified-http-client\n\nTypeScript client for\n[ai-api-unified-http](https://github.com/davecthomas/ai-api-unified-http).\n\nThe service describes itself at `/openapi.json`: every endpoint, every field\nyou can send, every field that comes back. A tool reads that description and\nwrites `src/schema.ts` from it. Nobody types those shapes by hand, which is\nwhat \"generated\" means here.\n\nThe editor then knows the field names, so a typo or a missing required field\nis an error before the code runs. Without it, the same mistake reaches the\nserver and comes back as a 422.\n\n```ts\nclient.raw.POST(\"/v1/completions\", { body: { engine: \"claude\", promt: \"hi\" } });\n//                                                             ^^^^^ caught here\n```\n\nCI regenerates the file on every pull request and fails when the committed\nversion has moved, so the client cannot fall behind the service it describes.\n\n## Install\n\nThe package ships TypeScript source, so a bundler compiles it with your app.\n\n```bash\nnpm install github:davecthomas/ai-api-unified-http#main\n```\n\n## Use\n\n```ts\nimport { createAiApiClient } from \"@davecthomas/ai-api-unified-http-client\";\n\nconst client = createAiApiClient({\n  baseUrl: \"https://your-service.run.app\",\n  apiKey: process.env.API_KEY!,\n  caller: { callerId: \"user-42\" },   // splits provider spend per end user\n});\n\nconst { data, error } = await client.raw.POST(\"/v1/completions\", {\n  body: { engine: \"claude\", prompt: \"Name three primary colors.\" },\n});\n```\n\nPaths, bodies, and responses are checked against the generated schema, so a\nwrong field name or a missing required property is a compile error.\n\n### Streaming\n\nServer-sent events are outside what OpenAPI describes, so this part is\nhand-written:\n\n```ts\nfor await (const chunk of client.streamCompletion({\n  engine: \"claude\",\n  prompt: \"Count to five.\",\n})) {\n  process.stdout.write(chunk);\n}\n```\n\nA stream that fails mid-flight throws. The service sends a terminal `error`\nevent even though the response began with 200 — the status line was already\nsent when the failure happened — and this client raises it so a broken stream\ncannot read as a short one.\n\n### Cost attribution\n\n`callerId`, `sessionId`, and `workflowId` become `X-Caller-Id`, `X-Session-Id`,\nand `X-Workflow-Id`, which the service records against each call's cost. Pass\nthem once when constructing the client, or per call:\n\n```ts\nawait client.raw.POST(\"/v1/completions\", {\n  body: { engine: \"claude\", prompt: \"...\" },\n  headers: client.headersFor({ callerId: \"user-99\" }),\n});\n```\n\n## Publishing\n\nAuthentication is npm Trusted Publishing over OIDC, so this repository holds no\nnpm token. GitHub mints a short-lived credential scoped to one workflow, and\nnpm records the publisher as GitHub Actions.\n\nVersion 1.0.0 went up by hand, because trusted publishing is configured on a\npackage's own settings page and that page does not exist until the package\ndoes. That is no longer true, so configure it once at\n`npmjs.com/package/@davecthomas/ai-api-unified-http-client/access`:\n\n| Field | Value |\n|---|---|\n| Organization or user | `davecthomas` |\n| Repository | `ai-api-unified-http` |\n| Workflow filename | `publish-client.yml` |\n| Allowed actions | `npm publish` |\n\nUntil that is set, a tag-triggered publish fails on authentication rather than\nfalling back to anything.\n\nEvery publish after that is a tag:\n\n```bash\n# bump version in package.json first, then\ngit tag client-v1.1.0 && git push origin client-v1.1.0\n```\n\nThe workflow refuses to publish when the tag and `package.json` disagree, so a\ntag cannot claim a version the package does not carry.\n\n**Your npm account email becomes public when you publish.** It appears in the\nregistry's `maintainers` field, which anyone can read. Trusted publishing keeps\nyour address out of the per-version publisher record, and does nothing about\n`maintainers`. Use an address you are willing to make public.\n\n## Regenerate\n\nFrom the repository root, after changing the service's shapes:\n\n```bash\nmake client\n```\n\nThat dumps the spec from the app object, regenerates the types, and\ntypechecks. Commit the result; CI compares against it.\n\n## Live check\n\nWith the service running:\n\n```bash\nnpm run smoke                                  # localhost:8080, local-dev-key\nAPI_BASE=https://... API_KEY=... npm run smoke\n```\n\nIt calls health, a completion, a token count, the model catalog, and a stream,\nbecause only a real round trip proves the generated types and the wire format\nagree.\n","readmeFilename":"README.md"}