{"_id":"@0xzahed/api-response-toolkit","_rev":"4-b3d0f1960a07575003b45e904cb0ee51","name":"@0xzahed/api-response-toolkit","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@0xzahed/api-response-toolkit","version":"1.0.0","keywords":["express","fastify","api","response","error-handling","pagination","middleware","rest-api","typescript"],"author":{"url":"https://github.com/0xzahed","name":"0xzahed"},"license":"MIT","_id":"@0xzahed/api-response-toolkit@1.0.0","maintainers":[{"name":"0xzahed1","email":"zahed04x@gmail.com"}],"homepage":"https://github.com/0xzahed/api-response-toolkit#readme","bugs":{"url":"https://github.com/0xzahed/api-response-toolkit/issues"},"dist":{"shasum":"2419786f2100b3d5922d7bc6ae86654ddc186080","tarball":"https://registry.npmjs.org/@0xzahed/api-response-toolkit/-/api-response-toolkit-1.0.0.tgz","fileCount":29,"integrity":"sha512-O+b6KdqNaQ9SkB3+RRUAyPlz+bPZHRG63UaZI4P+PL5EGm+7Oi7MSKIWmh/FOz6JY52XW4Fc4Ao7V8yGB1KQHQ==","signatures":[{"sig":"MEYCIQDa+z761ePDweUNMp/AKWhdJjM3MNnK3n/0CHsKwCoouwIhAPgDTT4fs+jCkQZuB7yB/BDE8UglvP/sEZmQaF6CluLs","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70352},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./express":{"types":"./dist/express-entry.d.ts","import":"./dist/express-entry.js","require":"./dist/express-entry.cjs"},"./fastify":{"types":"./dist/fastify-entry.d.ts","import":"./dist/fastify-entry.js","require":"./dist/fastify-entry.cjs"}},"gitHead":"ba0600602e3e55ffef46af5e3812ae3af5d86f0a","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","prepare":"tsup","publish":"npm publish --access public","test:smoke":"node --test test/dist-smoke.mjs","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"0xzahed1","email":"zahed04x@gmail.com"},"repository":{"url":"git+https://github.com/0xzahed/api-response-toolkit.git","type":"git"},"_npmVersion":"10.9.8","description":"Standardize API responses, errors, and pagination for Express and Fastify apps.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"fastify-plugin":"^4.5.1"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","vitest":"3.2.7","esbuild":"0.28.2","express":"5.2.1","fastify":"5.12.1","typescript":"^5.4.5","@types/node":"^20.14.2","@types/express":"5.0.0"},"peerDependencies":{"express":">=4.17.0 <6","fastify":">=4.0.0 <6"},"peerDependenciesMeta":{"express":{"optional":true},"fastify":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/api-response-toolkit_1.0.0_1788720951582_0.7022969886452657","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@0xzahed/api-response-toolkit","version":"1.0.1","keywords":["express","fastify","api","response","error-handling","pagination","middleware","rest-api","typescript"],"author":{"url":"https://github.com/0xzahed","name":"0xzahed"},"license":"MIT","_id":"@0xzahed/api-response-toolkit@1.0.1","maintainers":[{"name":"0xzahed1","email":"zahed04x@gmail.com"}],"homepage":"https://github.com/0xzahed/api-response-toolkit#readme","bugs":{"url":"https://github.com/0xzahed/api-response-toolkit/issues"},"dist":{"shasum":"5b66752e9c64fed2ba1d8f5edd60829a70b942e2","tarball":"https://registry.npmjs.org/@0xzahed/api-response-toolkit/-/api-response-toolkit-1.0.1.tgz","fileCount":29,"integrity":"sha512-WlWarh7jYdp2+EogKCJrVkBl3b2LMTpaWdj/2KuLJUTykw/HCajAspGXz2fP+NrqwznxmCrlEQj1AFces0uv7w==","signatures":[{"sig":"MEUCIQCrp/1/U5/XFveI3Mt++SLfByjBSUYmXJCmdu8FjQHq5wIgI227uGIyNkh7zKLyvGlMPbCaddu3D1MHPFHvw4wxXx8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70306},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./express":{"types":"./dist/express-entry.d.ts","import":"./dist/express-entry.js","require":"./dist/express-entry.cjs"},"./fastify":{"types":"./dist/fastify-entry.d.ts","import":"./dist/fastify-entry.js","require":"./dist/fastify-entry.cjs"}},"gitHead":"ba0600602e3e55ffef46af5e3812ae3af5d86f0a","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","prepare":"tsup","test:smoke":"node --test test/dist-smoke.mjs","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"0xzahed1","email":"zahed04x@gmail.com"},"repository":{"url":"git+https://github.com/0xzahed/api-response-toolkit.git","type":"git"},"_npmVersion":"10.9.8","description":"Standardize API responses, errors, and pagination for Express and Fastify apps.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"fastify-plugin":"^4.5.1"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","vitest":"3.2.7","esbuild":"0.28.2","express":"5.2.1","fastify":"5.12.1","typescript":"^5.4.5","@types/node":"^20.14.2","@types/express":"5.0.0"},"peerDependencies":{"express":">=4.17.0 <6","fastify":">=4.0.0 <6"},"peerDependenciesMeta":{"express":{"optional":true},"fastify":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/api-response-toolkit_1.0.1_1788720980795_0.7232170229290693","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@0xzahed/api-response-toolkit","version":"1.0.2","keywords":["express","fastify","api","response","error-handling","pagination","middleware","rest-api","typescript"],"author":{"url":"https://github.com/0xzahed","name":"0xzahed"},"license":"MIT","_id":"@0xzahed/api-response-toolkit@1.0.2","maintainers":[{"name":"0xzahed1","email":"zahed04x@gmail.com"}],"homepage":"https://github.com/0xzahed/api-response-toolkit#readme","bugs":{"url":"https://github.com/0xzahed/api-response-toolkit/issues"},"dist":{"shasum":"e23526b36389bf0ad4b882af40b3f94ded37a5cf","tarball":"https://registry.npmjs.org/@0xzahed/api-response-toolkit/-/api-response-toolkit-1.0.2.tgz","fileCount":29,"integrity":"sha512-sbE2CSO3kjukPWYRV3ujr0MPzI+mpf5z7vtDZMm70m96WPA7ffQZpV/cFP+y11MN44AeD5+c8UMMErYjklTHWg==","signatures":[{"sig":"MEQCIGt1hzic0NOaaoGmpDKQywu7g3BDLz/cwrWACUx8XeMyAiBGCZEdzvkoerGftLSSfq1oJuom3RTYHhEUjg3saczLKw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70369},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./express":{"types":"./dist/express-entry.d.ts","import":"./dist/express-entry.js","require":"./dist/express-entry.cjs"},"./fastify":{"types":"./dist/fastify-entry.d.ts","import":"./dist/fastify-entry.js","require":"./dist/fastify-entry.cjs"}},"gitHead":"1249e4e43100ba5bd3327729b2010a2af00ddab2","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","prepare":"tsup","test:smoke":"node --test test/dist-smoke.mjs","test:watch":"vitest","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"0xzahed1","email":"zahed04x@gmail.com"},"repository":{"url":"git+https://github.com/0xzahed/api-response-toolkit.git","type":"git"},"_npmVersion":"10.9.8","description":"Standardize API responses, errors, and pagination for Express and Fastify apps.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"fastify-plugin":"^4.5.1"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","vitest":"3.2.7","esbuild":"0.28.2","express":"5.2.1","fastify":"5.12.1","typescript":"^5.4.5","@types/node":"^20.14.2","@types/express":"5.0.0"},"peerDependencies":{"express":">=4.17.0 <6","fastify":">=4.0.0 <6"},"peerDependenciesMeta":{"express":{"optional":true},"fastify":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/api-response-toolkit_1.0.2_1788722359146_0.8669457150289142","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@0xzahed/api-response-toolkit","version":"1.0.3","description":"Standardize API responses, errors, and pagination for Express and Fastify apps.","license":"MIT","author":{"name":"0xzahed","url":"https://github.com/0xzahed"},"homepage":"https://github.com/0xzahed/api-response-toolkit#readme","repository":{"type":"git","url":"git+https://github.com/0xzahed/api-response-toolkit.git"},"bugs":{"url":"https://github.com/0xzahed/api-response-toolkit/issues"},"keywords":["express","fastify","api","response","error-handling","pagination","middleware","rest-api","typescript"],"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./express":{"types":"./dist/express-entry.d.ts","import":"./dist/express-entry.js","require":"./dist/express-entry.cjs"},"./fastify":{"types":"./dist/fastify-entry.d.ts","import":"./dist/fastify-entry.js","require":"./dist/fastify-entry.cjs"}},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","test:smoke":"node --test test/dist-smoke.mjs","prepublishOnly":"npm run build && npm test","prepare":"tsup"},"peerDependencies":{"express":">=4.17.0 <6","fastify":">=4.0.0 <6"},"peerDependenciesMeta":{"express":{"optional":true},"fastify":{"optional":true}},"dependencies":{"fastify-plugin":"^4.5.1"},"devDependencies":{"@types/express":"5.0.0","@types/node":"^20.14.2","esbuild":"0.28.2","express":"5.2.1","fastify":"5.12.1","tsup":"8.5.1","typescript":"^5.4.5","vitest":"3.2.7"},"engines":{"node":">=18"},"_id":"@0xzahed/api-response-toolkit@1.0.3","gitHead":"5e8e484bcbe63ee0ea78cdf5f6c457c9adaa9977","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-xduTm90r3rpEapgboQNXNIcTjyV6EcCzrb/sIGSCP0l/axAZFEPqDf36Qe9y4KmHah/NSSRoSPmZA0m2gNs1PA==","shasum":"09e5c8f637e80d69fdafe5b0ab1cc5507af0281b","tarball":"https://registry.npmjs.org/@0xzahed/api-response-toolkit/-/api-response-toolkit-1.0.3.tgz","fileCount":29,"unpackedSize":70369,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEBf7hRPQJQgz5M+aB68ON/g2VWYU0j0jtg8TSldfQeoAiEAv5FLyloc4FzhwcGAQcQOKyL4ScryruksvqUVMmT5cZA="}]},"_npmUser":{"name":"0xzahed1","email":"zahed04x@gmail.com"},"directories":{},"maintainers":[{"name":"0xzahed1","email":"zahed04x@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/api-response-toolkit_1.0.3_1788722602707_0.042050544671973444"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-06T18:55:51.401Z","modified":"2026-09-06T19:23:23.036Z","1.0.0":"2026-09-06T18:55:51.729Z","1.0.1":"2026-09-06T18:56:20.946Z","1.0.2":"2026-09-06T19:19:19.297Z","1.0.3":"2026-09-06T19:23:22.860Z"},"bugs":{"url":"https://github.com/0xzahed/api-response-toolkit/issues"},"author":{"name":"0xzahed","url":"https://github.com/0xzahed"},"license":"MIT","homepage":"https://github.com/0xzahed/api-response-toolkit#readme","keywords":["express","fastify","api","response","error-handling","pagination","middleware","rest-api","typescript"],"repository":{"type":"git","url":"git+https://github.com/0xzahed/api-response-toolkit.git"},"description":"Standardize API responses, errors, and pagination for Express and Fastify apps.","maintainers":[{"name":"0xzahed1","email":"zahed04x@gmail.com"}],"readme":"# @0xzahed/api-response-toolkit\n\nStandardize API responses, error handling, and pagination across your Express or Fastify backend — so every endpoint returns the same predictable JSON shape.\n\n```json\n{\n  \"success\": true,\n  \"message\": \"User fetched\",\n  \"data\": { \"id\": 1, \"name\": \"Ada\" },\n  \"meta\": null,\n  \"timestamp\": \"2026-09-06T18:00:00.000Z\"\n}\n```\n\n## Why\n\nWithout a convention, every route in a codebase ends up shaping its JSON differently — `{data}`, `{result}`, `{user}`, raw arrays, inconsistent error fields. This makes frontend consumption and error handling unpredictable. This toolkit gives you one shape for success, one shape for errors, and one shape for paginated lists, plus the middleware to enforce it with almost no boilerplate.\n\n## Install\n\n```bash\nnpm install @0xzahed/api-response-toolkit\n```\n\nExpress and Fastify are peer dependencies — install whichever framework you use:\n\n```bash\nnpm install express\n# or\nnpm install fastify\n```\n\n## Quick start — Express\n\n```js\nimport express from \"express\";\nimport {\n  responseToolkit,\n  errorHandler,\n  asyncHandler,\n  NotFoundError,\n} from \"@0xzahed/api-response-toolkit/express\";\n\nconst app = express();\napp.use(express.json());\napp.use(responseToolkit()); // attaches res.success / res.error / res.paginate\n\napp.get(\"/users/:id\", asyncHandler(async (req, res) => {\n  const user = await db.users.find(req.params.id);\n  if (!user) throw new NotFoundError(\"User not found\");\n  res.success(user, \"User fetched\");\n}));\n\napp.get(\"/users\", asyncHandler(async (req, res) => {\n  const { rows, total } = await db.users.list({ page: 1, limit: 20 });\n  res.paginate(rows, { page: 1, limit: 20, total });\n}));\n\napp.use(errorHandler()); // register LAST — formats thrown errors\n\napp.listen(3000);\n```\n\n## Quick start — Fastify\n\n```js\nimport Fastify from \"fastify\";\nimport { responseToolkit, NotFoundError } from \"@0xzahed/api-response-toolkit/fastify\";\n\nconst fastify = Fastify();\nawait fastify.register(responseToolkit);\n\nfastify.get(\"/users/:id\", async (req, reply) => {\n  const user = await db.users.find(req.params.id);\n  if (!user) throw new NotFoundError(\"User not found\");\n  reply.success(user, \"User fetched\");\n});\n\nfastify.get(\"/users\", async (req, reply) => {\n  const { rows, total } = await db.users.list({ page: 1, limit: 20 });\n  reply.paginate(rows, { page: 1, limit: 20, total });\n});\n\nfastify.listen({ port: 3000 });\n```\n\nFastify's global error handler (registered automatically by the plugin) formats any thrown `AppError` the same way as Express.\n\n## Response shapes\n\n**Success** — `success(data, message?, meta?)`\n```json\n{ \"success\": true, \"message\": \"Success\", \"data\": {}, \"meta\": null, \"timestamp\": \"...\" }\n```\n\n**Error** — `error(message?, statusCode?, errorCode?, details?)`\n```json\n{ \"success\": false, \"message\": \"Not found\", \"errorCode\": \"NOT_FOUND\", \"details\": null, \"timestamp\": \"...\" }\n```\n\n**Paginated** — `paginate(data, { page, limit, total })`\n```json\n{\n  \"success\": true,\n  \"data\": [],\n  \"pagination\": {\n    \"page\": 1, \"limit\": 20, \"total\": 87,\n    \"totalPages\": 5, \"hasNext\": true, \"hasPrev\": false\n  }\n}\n```\n\n## Error classes\n\nAll extend `AppError` and carry a matching `statusCode` and `errorCode`, so `throw`ing them from any route (sync or async, wrapped in `asyncHandler`) results in the correctly formatted error response automatically.\n\n| Class | Status | Code |\n|---|---|---|\n| `NotFoundError` | 404 | `NOT_FOUND` |\n| `ValidationError` | 400 | `VALIDATION_ERROR` |\n| `UnauthorizedError` | 401 | `UNAUTHORIZED` |\n| `ForbiddenError` | 403 | `FORBIDDEN` |\n| `ConflictError` | 409 | `CONFLICT` |\n| `AppError` | custom | custom |\n\n```js\nthrow new ValidationError(\"Invalid email\", { field: \"email\" });\nthrow new AppError(\"Rate limited\", 429, \"RATE_LIMITED\");\n```\n\nUnexpected errors (anything that isn't an `AppError`, e.g. a database connection failure) are caught by the global error handler and returned as a generic `500 / INTERNAL_ERROR` with message `\"Internal server error\"` — the original error message is never leaked to the client. Client errors (4xx) from framework-level failures (e.g. malformed JSON body, schema validation) are surfaced with a `REQUEST_ERROR` or `VALIDATION_ERROR` code and their status preserved.\n\n## API reference\n\n### Core (framework-agnostic)\nImport from `\"@0xzahed/api-response-toolkit\"`:\n- `success(data, message?, meta?)`\n- `error(message?, statusCode?, errorCode?, details?)`\n- `paginate(data, { page, limit, total })`\n- `AppError`, `NotFoundError`, `ValidationError`, `UnauthorizedError`, `ForbiddenError`, `ConflictError`\n\n### Express (`@0xzahed/api-response-toolkit/express`)\n- `responseToolkit()` — middleware attaching `res.success`, `res.error`, `res.paginate`\n- `errorHandler(options?)` — global error-formatting middleware (register last); `options.logger` overrides the default `console.error`\n- `asyncHandler(fn)` — wraps an async route handler so rejected promises reach `errorHandler` without try/catch\n\n### Fastify (`@0xzahed/api-response-toolkit/fastify`)\n- `responseToolkit` — plugin (register with `fastify.register(...)`) attaching `reply.success`, `reply.error`, `reply.paginate`, and a global error handler\n\n## TypeScript\n\nFully typed — response shapes, error classes, and framework decorators (`res.success`, `reply.error`, etc.) all have proper type definitions, including augmented `Request`/`Reply` types for Express and Fastify.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}