{"_id":"@arkhai/apitokens-middleware","_rev":"2-b7e56f4ebe0d5eca2e803704c05d84e0","name":"@arkhai/apitokens-middleware","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@arkhai/apitokens-middleware","version":"0.1.0","license":"UNLICENSED","_id":"@arkhai/apitokens-middleware@0.1.0","maintainers":[{"name":"mlegls","email":"yz@mmon.co"}],"homepage":"https://github.com/arkhai-io/simple-compute-market/tree/main/domains/apitokens/middleware/typescript#readme","bugs":{"url":"https://github.com/arkhai-io/simple-compute-market/issues"},"dist":{"shasum":"6dd64171e6e9609da9c1d1e9d47d44486b673c12","tarball":"https://registry.npmjs.org/@arkhai/apitokens-middleware/-/apitokens-middleware-0.1.0.tgz","fileCount":27,"integrity":"sha512-XI39wrw4kFDNa9+XIPsOde0ABPdp7soZcGd2tQATZ9BBE5Cp+qtDBd4GYljzKGaZNCmzI6DYQuXL6FWpm3PTmg==","signatures":[{"sig":"MEUCIFmDMBOSllzESh4fW0UPj1AWBn22lqKe+2pvHrPvvwt5AiEA/vwYsmJb32ykPKZVSOB8njfzhFXvvcvPNP1lIgQUNh0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82194},"main":"./dist/src/index.js","type":"module","types":"./dist/src/index.d.ts","engines":{"node":">=22.6"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"}},"gitHead":"711502584dd3f67e31f8015bc60344bf4df1d1a8","scripts":{"test":"node --test 'test/*.test.ts'","build":"tsc -p tsconfig.json","check":"npm run typecheck && npm run test","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"mlegls","email":"yz@mmon.co"},"repository":{"url":"git+https://github.com/arkhai-io/simple-compute-market.git","type":"git","directory":"domains/apitokens/middleware/typescript"},"_npmVersion":"11.12.1","description":"Seller-side API-tokens gating middleware: verify + meter prepaid API credits against the tokens service, map exhaustion to a 402 with a purchase pointer. Behavioral parity with the Python and Rust middlewares (../conformance).","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/apitokens-middleware_0.1.0_1781587376482_0.5091248159452026","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@arkhai/apitokens-middleware","version":"0.1.1","description":"Seller-side API-tokens gating middleware: verify + meter prepaid API credits against the tokens service, map exhaustion to a 402 with a purchase pointer. Behavioral parity with the Python and Rust middlewares (../conformance).","type":"module","license":"MIT","repository":{"type":"git","url":"git+https://github.com/arkhai-io/simple-compute-market.git","directory":"domains/apitokens/middleware/typescript"},"homepage":"https://github.com/arkhai-io/simple-compute-market/tree/main/domains/apitokens/middleware/typescript#readme","bugs":{"url":"https://github.com/arkhai-io/simple-compute-market/issues"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"}},"main":"./dist/src/index.js","types":"./dist/src/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"node --test 'test/*.test.ts'","check":"npm run typecheck && npm run test","prepublishOnly":"npm run build"},"publishConfig":{"access":"public"},"engines":{"node":">=22.6"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.6.0"},"gitHead":"bf719588077c058ca1c15cc4c9be28cf384b5f55","_id":"@arkhai/apitokens-middleware@0.1.1","_nodeVersion":"22.22.3","_npmVersion":"11.17.0","dist":{"integrity":"sha512-35ySdKBOU7ojJoRxsgm82tp7OM9xvTJ851uX7ouq9J0cRrZHYkgVFhfjN+f/RpujLitnjZ/hm5fX+WkfHe38qw==","shasum":"7ad675f2026daa54f269e77b4c9cf91ef248f71d","tarball":"https://registry.npmjs.org/@arkhai/apitokens-middleware/-/apitokens-middleware-0.1.1.tgz","fileCount":27,"unpackedSize":83559,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arkhai%2fapitokens-middleware@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIESrWsqr2khQeGms33BS/i+HOIkUkixA6bUEkcpMRCgYAiEAhiDNashBGRg8bDNFMZWOTaAhy/872iT93fesjIL7dvg="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:91cc7ae8-b54b-405a-af41-77079c3b85a8"}},"directories":{},"maintainers":[{"name":"mlegls","email":"yz@mmon.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/apitokens-middleware_0.1.1_1781589535934_0.8065974061321755"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-16T05:22:56.239Z","modified":"2026-06-16T05:58:56.377Z","0.1.0":"2026-06-16T05:22:56.631Z","0.1.1":"2026-06-16T05:58:56.086Z"},"bugs":{"url":"https://github.com/arkhai-io/simple-compute-market/issues"},"license":"MIT","homepage":"https://github.com/arkhai-io/simple-compute-market/tree/main/domains/apitokens/middleware/typescript#readme","repository":{"type":"git","url":"git+https://github.com/arkhai-io/simple-compute-market.git","directory":"domains/apitokens/middleware/typescript"},"description":"Seller-side API-tokens gating middleware: verify + meter prepaid API credits against the tokens service, map exhaustion to a 402 with a purchase pointer. Behavioral parity with the Python and Rust middlewares (../conformance).","maintainers":[{"name":"mlegls","email":"yz@mmon.co"}],"readme":"# @arkhai/apitokens-middleware (TypeScript)\n\nSeller-side gating middleware for the API-tokens domain — the\nTypeScript sibling of the Python reference\n(`../python`). It extracts the bearer key from the `Authorization`\nheader, verifies it against the tokens service (short-TTL cache), meters\neach request by consuming credits (synchronously near exhaustion,\noptionally batched above a low-balance threshold), and maps a drained\nkey to a 402 whose body carries a `purchase` pointer (the re-purchase\nloop). All verification and accounting authority stays in the service.\n\nThe behavioral contract — status codes, machine-readable bodies, and\nper-step service-call counts — is shared with the Python and Rust\nmiddlewares and pinned by `../conformance/session.json`.\n\n## Install\n\n```sh\nnpm install @arkhai/apitokens-middleware\n```\n\nRequires Node ≥ 22.6 (per `engines`). The package is published with\n[provenance](https://docs.npmjs.com/generating-provenance-statements).\n\n## Use\n\nTwo framework-neutral bindings ship from the package root. Both gate\nevery request before it reaches the app and return a `402` with a\n`purchase` pointer once a key is drained; `excludePaths` defaults to\n`[\"/health\"]`.\n\nConnect/Express:\n\n```ts\nimport express from \"express\";\nimport { tokenGateMiddleware, gateConfigFromEnv } from \"@arkhai/apitokens-middleware\";\n\nconst app = express();\napp.use(tokenGateMiddleware({ config: gateConfigFromEnv() }));\n// ... your routes\n```\n\nWeb `fetch` handler (Workers, Deno, Bun, …):\n\n```ts\nimport { withTokenGate, gateConfig } from \"@arkhai/apitokens-middleware\";\n\nconst fetchHandler = withTokenGate(\n  { config: gateConfig({ serviceUrl: \"http://localhost:8082\", adminKey: process.env.ADMIN_KEY }) },\n  async (_req) => Response.json({ ok: true }),\n);\nexport default { fetch: fetchHandler };\n```\n\n`gateConfigFromEnv()` reads `APITOKENS_MIDDLEWARE_*` variables\n(`SERVICE_URL`, `ADMIN_KEY`, `AMOUNT_PER_REQUEST`, the `PURCHASE_*`\npointer fields, …); `gateConfig({ serviceUrl, … })` takes the same\nfields inline. All verification and accounting authority stays in the\ntokens service — the gate only caches and meters.\n\n## Layout\n\n- `src/config.ts` — `GateConfig` / `PurchasePointer` (+ `gateConfigFromEnv`).\n- `src/client.ts` — `TokensClient` over `fetch`, and the `TokensApi`\n  interface the gate depends on.\n- `src/gate.ts` — framework-neutral `TokenGate` (verify cache, balance\n  estimate, batched-charge accumulator), `parseBearer`,\n  `keyIdFromSecret`.\n- `src/adapter.ts` — two bindings: a Connect/Express middleware\n  (`tokenGateMiddleware`) and a Web `fetch` wrapper (`withTokenGate`).\n  Neither imports a framework.\n\n## Develop\n\nRequires Node ≥ 22.6 (native TypeScript type-stripping; tests run `.ts`\ndirectly).\n\n```sh\nnpm install\nnpm run typecheck      # tsc --noEmit\nnpm test               # node --test over the conformance + gate suites\nnpm run check          # typecheck + test\nnpm run build          # emit dist/ (.js + .d.ts) for publishing\n```\n\n`test/conformanceRunner.ts` is the reference harness: it stands up an\nin-process scripted tokens service (`test/scriptedService.ts`) and\ndrives the **real** `fetch` client against it, replaying\n`../conformance/session.json` step for step and asserting the decision\nplus the per-step verify/consume call counts — mirroring the Python\nrunner at the HTTP layer.\n","readmeFilename":"README.md"}