{"_id":"@superfunctions/http","_rev":"6-0630f2948b0dd1db0523eedf5af62073","name":"@superfunctions/http","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@superfunctions/http","version":"0.1.0","keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"author":{"name":"21n"},"license":"MIT","_id":"@superfunctions/http@0.1.0","maintainers":[{"name":"21native","email":"npm@21n.org"}],"homepage":"https://github.com/21nCo/super-functions#readme","bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"dist":{"shasum":"93510a4202f79416f667958d0fa73f8240b870b2","tarball":"https://registry.npmjs.org/@superfunctions/http/-/http-0.1.0.tgz","fileCount":38,"integrity":"sha512-8jw6W+1G8rJtsZ6zk+NBhVhG/KOMD7QFJQv7UsEo3xYk+/CxPPsQ2zaQBu6+eb1fN5FQDxqwsKOFVg6JKjI1aw==","signatures":[{"sig":"MEQCIDsoDCgyHCK9IzEcr8DFbzvbwWANLcNhQyKvMlLyXtp5AiA+HVbmHg/QBDHmulWDVtqC4DGrUu1dvGxfss+ENe1sFQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49745},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./types":{"types":"./dist/types.d.ts"},"./middleware":{"types":"./dist/middleware/index.d.ts","default":"./dist/middleware/index.js"}},"gitHead":"b1140ab1f60ad8bd57fe814cd244d543964ba55d","scripts":{"lint":"echo 'lint not configured'","test":"vitest","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest --watch"},"_npmUser":{"name":"21native","email":"npm@21n.org"},"repository":{"url":"git+https://github.com/21nCo/super-functions.git","type":"git","directory":"packages/http"},"_npmVersion":"11.6.1","description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","directories":{},"_nodeVersion":"23.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/http_0.1.0_1765363485944_0.03074447985785178","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@superfunctions/http","version":"0.1.1","keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"author":{"name":"21n"},"license":"MIT","_id":"@superfunctions/http@0.1.1","maintainers":[{"name":"21native","email":"npm@21n.org"}],"homepage":"https://github.com/21nCo/super-functions#readme","bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"dist":{"shasum":"da954bc567940021918a6d4799ea3d39a96dad04","tarball":"https://registry.npmjs.org/@superfunctions/http/-/http-0.1.1.tgz","fileCount":38,"integrity":"sha512-yGX0Q1rPY1NvIOqVy5QZa8/WHcf5FIaPkEmwtZxlRV7foX3K6gI3dvbx1+78IT+AeT5bi3QjsbucLVOt5y4T4g==","signatures":[{"sig":"MEUCIFtE/JQM/W4FAB7WpSS9PKEGijkLwwswXYx+FPX0xHUsAiEA/9f6OV+RY9G1Z8T0dTCNUibMY8yb8LdVf8Qn0OEgduU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":49552},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./types":{"types":"./dist/types.d.ts"},"./middleware":{"types":"./dist/middleware/index.d.ts","default":"./dist/middleware/index.js"}},"gitHead":"b1140ab1f60ad8bd57fe814cd244d543964ba55d","scripts":{"lint":"echo 'lint not configured'","test":"vitest","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest --watch"},"_npmUser":{"name":"21native","email":"npm@21n.org"},"repository":{"url":"git+https://github.com/21nCo/super-functions.git","type":"git","directory":"packages/http"},"_npmVersion":"11.6.1","description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","directories":{},"_nodeVersion":"23.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/http_0.1.1_1765363783307_0.5587910667014593","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@superfunctions/http","version":"0.1.2","keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"author":{"name":"21n"},"license":"MIT","_id":"@superfunctions/http@0.1.2","maintainers":[{"name":"21native","email":"npm@21n.org"}],"homepage":"https://github.com/21nCo/super-functions#readme","bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"dist":{"shasum":"0b4a41337c6097be21f1a47be9ce27c648b250d8","tarball":"https://registry.npmjs.org/@superfunctions/http/-/http-0.1.2.tgz","fileCount":38,"integrity":"sha512-6Zuw9A/+XqReK7RqI7I5/PKkJgH9a9a2q/PYBxk7/Aj5fPhMOVM/K1ZPOcdXgtsef3ZGJlaMhxdaie2zbH7BcQ==","signatures":[{"sig":"MEUCIA4SIG8WMQ11lKiFxTr6HX7jZKJXifge1458OX+d4r7yAiEArG1piCgxvVOecDUnaqFuge5wWZh6NCj4qCiHE0uYmOs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50505},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./types":{"types":"./dist/types.d.ts"},"./middleware":{"types":"./dist/middleware/index.d.ts","default":"./dist/middleware/index.js"}},"gitHead":"b1140ab1f60ad8bd57fe814cd244d543964ba55d","scripts":{"lint":"echo 'lint not configured'","test":"vitest","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest --watch"},"_npmUser":{"name":"21native","email":"npm@21n.org"},"repository":{"url":"git+https://github.com/21nCo/super-functions.git","type":"git","directory":"packages/http"},"_npmVersion":"11.6.1","description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","directories":{},"_nodeVersion":"23.11.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/http_0.1.2_1767624291529_0.32549016148544574","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@superfunctions/http","version":"0.1.3","keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"author":{"name":"21n"},"license":"MIT","_id":"@superfunctions/http@0.1.3","maintainers":[{"name":"21native","email":"npm@21n.org"}],"homepage":"https://github.com/21nCo/super-functions#readme","bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"dist":{"shasum":"cfa7a66069854602f6a44316d368765bd03eda4f","tarball":"https://registry.npmjs.org/@superfunctions/http/-/http-0.1.3.tgz","fileCount":42,"integrity":"sha512-gGn6hyUxbFBFG6Q+mwHFMVL0w1CTbEhqY5UJ5CMkwP0ZFoYlcIcqyIzy7dGBiDmMso4Rz+PLvtrX9jsylcS0bg==","signatures":[{"sig":"MEYCIQC3p8C5qFE77wrL0jNF/E9YBig35bfHC7dClxq8jc8MUQIhAL3WZig2fI4jUJEb5KqZoePkhQ5dlISmI2VKr9JtecjG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63820},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./types":{"types":"./dist/types.d.ts"},"./middleware":{"types":"./dist/middleware/index.d.ts","default":"./dist/middleware/index.js"}},"gitHead":"13d0068a71d6b6d560853e74e4ef7672eabd431f","scripts":{"lint":"echo 'lint not configured'","test":"vitest","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest --watch"},"_npmUser":{"name":"21native","email":"npm@21n.org"},"repository":{"url":"git+https://github.com/21nCo/super-functions.git","type":"git","directory":"packages/http"},"_npmVersion":"10.8.2","description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/http_0.1.3_1778738847857_0.009054918094359543","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@superfunctions/http","version":"0.2.0","keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"author":{"name":"21n"},"license":"MIT","_id":"@superfunctions/http@0.2.0","maintainers":[{"name":"21native","email":"npm@21n.org"}],"homepage":"https://github.com/21nCo/super-functions#readme","bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"dist":{"shasum":"c46cb642053464fcb15b479b377d34d01acd1b87","tarball":"https://registry.npmjs.org/@superfunctions/http/-/http-0.2.0.tgz","fileCount":46,"integrity":"sha512-t4vDDXGu+h0/Yjn0KiEYuNsNB84JyOAJToZaYodDtAHIT3HVAIT6GbSxMOQJV83gw8XxyuCE8JqhFqKXFGfmog==","signatures":[{"sig":"MEQCIA4kD6Rpkh0FQbN6dFP4c7H4l1NsGFoWNrme+ftuaycIAiBICPr+NG6C9V27n54t1SfbJjI47yRszRcTemwFV2TvnQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":96752},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./types":{"types":"./dist/types.d.ts"},"./middleware":{"types":"./dist/middleware/index.d.ts","default":"./dist/middleware/index.js"}},"gitHead":"e11bd81db6390dbc38303a5f3da6baadbaef0c8b","scripts":{"lint":"echo 'lint not configured'","test":"vitest","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","test:watch":"vitest --watch"},"_npmUser":{"name":"21native","email":"npm@21n.org"},"repository":{"url":"git+https://github.com/21nCo/super-functions.git","type":"git","directory":"packages/http"},"_npmVersion":"10.8.2","description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@superfunctions/observability":"0.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.4","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/http_0.2.0_1787980924715_0.02277148503047144","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@superfunctions/http","version":"0.3.0","description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./middleware":{"types":"./dist/middleware/index.d.ts","default":"./dist/middleware/index.js"},"./types":{"types":"./dist/types.d.ts"}},"scripts":{"build":"tsc","test":"vitest","test:watch":"vitest --watch","lint":"echo 'lint not configured'","typecheck":"tsc --noEmit","clean":"rm -rf dist"},"keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"author":{"name":"21n"},"license":"MIT","bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"repository":{"type":"git","url":"git+https://github.com/21nCo/super-functions.git","directory":"packages/http"},"publishConfig":{"access":"public"},"dependencies":{"@superfunctions/observability":"0.0.1"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.6.0","vitest":"^3.2.4"},"_id":"@superfunctions/http@0.3.0","gitHead":"76ea582129eb3a3968844652a94eedcbe468fe2f","homepage":"https://github.com/21nCo/super-functions#readme","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-G1JFyzfWGpAgTlnfDVMMJ8tT/g207WN5CyfhQL2kOwaBWlYOkF+qUkQ2zS2mB1N5/IhDpQ8Qdf5e0Ot+ssIJmg==","shasum":"2b15f137ccd0c25b2f43c5e70c41edac01a07fba","tarball":"https://registry.npmjs.org/@superfunctions/http/-/http-0.3.0.tgz","fileCount":46,"unpackedSize":97236,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCFd6NAxYll9tI6xrgX7NsTu46/t7lVE5sVD6JeDN4qLwIhAISmi+6cZzxmVJwy2xqmuM4a/rkFcPb4aY8R6q2CydfB"}]},"_npmUser":{"name":"21native","email":"npm@21n.org"},"directories":{},"maintainers":[{"name":"21native","email":"npm@21n.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/http_0.3.0_1789489979549_0.7519921155683176"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-10T10:44:45.805Z","modified":"2026-09-15T16:32:59.895Z","0.1.0":"2025-12-10T10:44:46.095Z","0.1.1":"2025-12-10T10:49:43.446Z","0.1.2":"2026-01-05T14:44:51.679Z","0.1.3":"2026-05-14T06:07:28.010Z","0.2.0":"2026-08-29T05:22:04.854Z","0.3.0":"2026-09-15T16:32:59.695Z"},"bugs":{"url":"https://github.com/21nCo/super-functions/issues"},"author":{"name":"21n"},"license":"MIT","homepage":"https://github.com/21nCo/super-functions#readme","keywords":["http","router","framework-agnostic","web-standard","express","hono","fastify","superfunctions"],"repository":{"type":"git","url":"git+https://github.com/21nCo/super-functions.git","directory":"packages/http"},"description":"Framework-agnostic HTTP abstraction layer for Superfunctions libraries","maintainers":[{"name":"21native","email":"npm@21n.org"}],"readme":"# @superfunctions/http\n\nFramework-agnostic HTTP abstraction layer for building web APIs that work across Express, Hono, Fastify, Next.js, and more.\n\n## Installation\n\n```bash\nnpm install @superfunctions/http\n```\n\nFor framework adapters:\n\n```bash\n# Express\nnpm install @superfunctions/http-express\n\n# Hono\nnpm install @superfunctions/http-hono\n\n# Fastify\nnpm install @superfunctions/http-fastify\n\n# Next.js\nnpm install @superfunctions/http-next\n\n# SvelteKit\nnpm install @superfunctions/http-sveltekit\n```\n\n## Quick Start\n\n### Define Your API (Framework Agnostic)\n\n```typescript\nimport { createRouter } from '@superfunctions/http';\n\nconst apiRouter = createRouter({\n  routes: [\n    {\n      method: 'GET',\n      path: '/users',\n      handler: async () => {\n        const users = await db.query('SELECT * FROM users');\n        return Response.json(users);\n      },\n    },\n    {\n      method: 'GET',\n      path: '/users/:id',\n      handler: async (req, ctx) => {\n        const user = await db.query(\n          'SELECT * FROM users WHERE id = ?',\n          [ctx.params.id]\n        );\n        return Response.json(user);\n      },\n    },\n    {\n      method: 'POST',\n      path: '/users',\n      handler: async (req, ctx) => {\n        const data = await ctx.json();\n        const user = await db.insert('users', data);\n        return Response.json(user, { status: 201 });\n      },\n    },\n  ],\n});\n```\n\n### Use with Express\n\n```typescript\nimport express from 'express';\nimport { toExpress } from '@superfunctions/http-express';\nimport { apiRouter } from './api';\n\nconst app = express();\napp.use(express.json());\napp.use('/api', toExpress(apiRouter));\napp.listen(3000);\n```\n\n### Use with Hono\n\n```typescript\nimport { Hono } from 'hono';\nimport { toHono } from '@superfunctions/http-hono';\nimport { apiRouter } from './api';\n\nconst app = new Hono();\napp.route('/api', toHono(apiRouter));\n\nexport default app;\n```\n\n### Use Directly (Universal Handler)\n\nFor Fetch-native frameworks:\n\n```typescript\nimport { createRouter } from '@superfunctions/http';\n\nconst router = createRouter({ routes: [...] });\n\n// Cloudflare Workers\nexport default {\n  fetch: router.handle\n};\n\n// Deno\nDeno.serve(router.handle);\n\n// Bun\nBun.serve({ fetch: router.handle });\n```\n\n## Features\n\n### Middleware\n\n```typescript\nconst authMiddleware = async (req, ctx, next) => {\n  const token = req.headers.get('Authorization');\n  if (!token) {\n    return Response.json({ error: 'Unauthorized' }, { status: 401 });\n  }\n  ctx.user = await verifyToken(token);\n  return next();\n};\n\nconst router = createRouter({\n  middleware: [authMiddleware],\n  routes: [...],\n});\n```\n\n### Context\n\n```typescript\ninterface AppContext {\n  db: Database;\n  user?: User;\n}\n\nconst router = createRouter<AppContext>({\n  context: async (req) => ({\n    db: adapter,\n    user: await getUser(req),\n  }),\n  routes: [\n    {\n      method: 'GET',\n      path: '/profile',\n      handler: async (req, ctx) => {\n        // ctx is typed as AppContext & RouteContext\n        return Response.json({ user: ctx.user });\n      },\n    },\n  ],\n});\n```\n\n### Error Handling\n\n```typescript\nimport { RouterError, UnauthorizedError } from '@superfunctions/http';\n\nconst router = createRouter({\n  routes: [\n    {\n      method: 'GET',\n      path: '/protected',\n      handler: async () => {\n        throw new UnauthorizedError('Invalid token');\n      },\n    },\n  ],\n  onError: (error, req) => {\n    console.error('Error:', error);\n    return Response.json(\n      { error: error.message },\n      { status: error instanceof RouterError ? error.statusCode : 500 }\n    );\n  },\n});\n```\n\n### Base Path\n\n**⚠️ Important: Only use `basePath` for standalone deployments without framework mounting.**\n\n```typescript\n// ✅ Good: Standalone deployment (Cloudflare Workers, Vercel Edge)\nconst router = createRouter({\n  basePath: '/api/v1',\n  routes: [\n    { method: 'GET', path: '/users', handler: ... } // Accessible at /api/v1/users\n  ]\n});\n\nexport default { fetch: router.handle }; // or router.handler\n\n// ❌ Bad: With framework mounting (creates double prefixing)\nconst router = createRouter({\n  basePath: '/v1',  // Don't do this!\n  routes: [...]\n});\napp.use('/api', toExpress(router)); // Would need /api/v1/users\n\n// ✅ Good: With framework mounting (no basePath)\nconst router = createRouter({\n  routes: [\n    { method: 'GET', path: '/users', handler: ... }\n  ]\n});\napp.use('/api/v1', toExpress(router)); // Accessible at /api/v1/users\n```\n\n**Rule of thumb:**\n- **Standalone deployment** → Use `basePath` in router\n- **Framework mounting** → Use framework's mounting (e.g., `app.use('/path', ...)`) and omit `basePath`\n\n### CORS\n\n```typescript\nimport { corsMiddleware } from '@superfunctions/http/middleware';\n\nconst router = createRouter({\n  middleware: [\n    corsMiddleware({\n      origin: 'https://example.com',\n      methods: ['GET', 'POST'],\n      credentials: true,\n    }),\n  ],\n  routes: [...],\n});\n```\n\n## API Reference\n\n### `createRouter<TContext>(options)`\n\nCreates a framework-agnostic router.\n\n**Options:**\n- `routes`: Array of route definitions\n- `middleware?`: Global middleware array\n- `context?`: Static context or factory function\n- `onError?`: Custom error handler\n- `basePath?`: Base path prefix for all routes\n- `cors?`: CORS configuration\n\n**Returns:** `Router<TContext>`\n\n### Route Definition\n\n```typescript\ninterface Route<TContext> {\n  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';\n  path: string;\n  handler: RouteHandler<TContext>;\n  middleware?: Middleware<TContext>[];\n  meta?: Record<string, any>;\n}\n```\n\n### Route Context\n\nEvery handler receives a context with:\n\n```typescript\ninterface RouteContext {\n  params: Record<string, string>;  // Path parameters\n  query: URLSearchParams;          // Query string\n  url: URL;                        // Full URL\n  json: () => Promise<any>;        // Parse JSON body\n  formData: () => Promise<FormData>; // Parse form data\n  text: () => Promise<string>;     // Get text body\n}\n```\n\n## Framework Adapters\n\n| Framework | Package | Function |\n|-----------|---------|----------|\n| Express | `@superfunctions/http-express` | `toExpress()`, `toExpressHandler()` |\n| Hono | `@superfunctions/http-hono` | `toHono()` |\n| Fastify | `@superfunctions/http-fastify` | `toFastify()` |\n| Next.js | `@superfunctions/http-next` | `toNextHandlers()` |\n| SvelteKit | `@superfunctions/http-sveltekit` | `toSvelteKitHandler()`, `toSvelteKitHandlers()` |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}