{"_id":"@airnauts/comments-server","_rev":"8-765364a80e3a1eab7403fcccfbc054d4","name":"@airnauts/comments-server","dist-tags":{"latest":"0.7.0"},"versions":{"0.1.0":{"name":"@airnauts/comments-server","version":"0.1.0","keywords":["comments","commenting","annotations","feedback","airnauts","server","nextjs"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.1.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"37e506ec679f3d0f7c36d7a4c6ade024804f2b37","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.1.0.tgz","fileCount":55,"integrity":"sha512-RpP3W5J5KT+OM+ukgW7KZE2MEf9rYCAyGlkk8Q/L579ooeYBzrUISDuKmrCerpF3+zWfWCkjv1fK0W0eGftS+g==","signatures":[{"sig":"MEQCIFLVRQ9ml7gkKCCgChIYbYpiEqoeeWK9S166p65JUy/VAiApqwmzc6/YF5vzch9KCbuhfDLvZd8M1S3mxcUsL+sdmg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109990},"type":"module","_from":"file:airnauts-comments-server-0.1.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/private/var/folders/2n/cymmpn8j3p962bjb2kqxq7n80000gn/T/7f6ca8512c569a9e54f0f2bb5a1b1922/airnauts-comments-server-0.1.0.tgz","_integrity":"sha512-RpP3W5J5KT+OM+ukgW7KZE2MEf9rYCAyGlkk8Q/L579ooeYBzrUISDuKmrCerpF3+zWfWCkjv1fK0W0eGftS+g==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.2","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, Next.js).","directories":{},"_nodeVersion":"22.13.0","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.1.0_1780410891905_0.2462319819503005","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."},"0.2.0":{"name":"@airnauts/comments-server","version":"0.2.0","keywords":["comments","commenting","annotations","feedback","airnauts","server","nextjs"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.2.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"d022f5203ab0d53293d380739e9eab3a8f84c1a5","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.2.0.tgz","fileCount":61,"integrity":"sha512-rLzHrbozh+xvMgGeDM2SkxZLq4ww1Of4FZ5tgQ6uNMLlOp1MypFyppZOBkj2o/REc4gDvEAnqpDktZRxC84DbQ==","signatures":[{"sig":"MEUCIQCefQrnPfUpxGYXXWGtaFoujMDEvEGVWnA6BWGiV7EbAgIgW70PADY5p4vbPSu1DdXGK95AE/tLmxqW2c/OghSBgWU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120609},"type":"module","_from":"file:airnauts-comments-server-0.2.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/99e2b91ce642ade55750fc15c0f8c9ec/airnauts-comments-server-0.2.0.tgz","_integrity":"sha512-rLzHrbozh+xvMgGeDM2SkxZLq4ww1Of4FZ5tgQ6uNMLlOp1MypFyppZOBkj2o/REc4gDvEAnqpDktZRxC84DbQ==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.8","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, Next.js).","directories":{},"_nodeVersion":"22.22.3","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.2.0_1780913165243_0.6881878310673326","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."},"0.4.0":{"name":"@airnauts/comments-server","version":"0.4.0","keywords":["comments","commenting","annotations","feedback","airnauts","server","nextjs"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.4.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"05eb93380914228947ae795bb2546836893a1e42","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.4.0.tgz","fileCount":61,"integrity":"sha512-D+wpLucPpR1P10Ta79VaL7r9BvbmOPnKoLzWebR/4lV6xwi2eKrHobDCidy0NXLjdYoAj3FbqNkebEpCrJYn7A==","signatures":[{"sig":"MEYCIQCgrTULH6oZZbyM2ZbUwocjqTfRxR3lwO8MW/NH6EKdYQIhAMKZFa5bUYqBW+iChnMezR4P09kiwMe0JDi8OqrH4ACi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120609},"type":"module","_from":"file:airnauts-comments-server-0.4.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/3a024c34df0cacee07a2f7a341d5ad22/airnauts-comments-server-0.4.0.tgz","_integrity":"sha512-D+wpLucPpR1P10Ta79VaL7r9BvbmOPnKoLzWebR/4lV6xwi2eKrHobDCidy0NXLjdYoAj3FbqNkebEpCrJYn7A==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.8","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, Next.js).","directories":{},"_nodeVersion":"22.22.3","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.4.0"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.4.0_1780915787793_0.9919449379418468","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."},"0.5.0":{"name":"@airnauts/comments-server","version":"0.5.0","keywords":["comments","commenting","annotations","feedback","airnauts","server","nextjs"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.5.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"b8ebf6597c33a8c62f65d8ac5f1d8e92e53fa38d","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.5.0.tgz","fileCount":61,"integrity":"sha512-kQXpIIwWVuBBsRfTNIw507nt7KTGXkf6UCFDAkzgej/V7ok1WT17pgGy/en9Ac+zxZRRfG1LCgXAbDtbrx9LBw==","signatures":[{"sig":"MEUCIQCqpE/qcgFtgRiwyGlGcBgf0m+TPKKBmqj5rhejW9W+tgIgfjv78fML0HfyRyUgkyyVDyC5W9vTOJVWp/80csiWfBA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120609},"type":"module","_from":"file:airnauts-comments-server-0.5.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/43188ee0177379d078d7bb6120ddc66c/airnauts-comments-server-0.5.0.tgz","_integrity":"sha512-kQXpIIwWVuBBsRfTNIw507nt7KTGXkf6UCFDAkzgej/V7ok1WT17pgGy/en9Ac+zxZRRfG1LCgXAbDtbrx9LBw==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.8","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, Next.js).","directories":{},"_nodeVersion":"22.22.3","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.5.0_1780919621024_0.019497844435068634","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."},"0.5.1":{"name":"@airnauts/comments-server","version":"0.5.1","keywords":["comments","commenting","annotations","feedback","airnauts","server","nextjs"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.5.1","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"fcf32c0e3e5442d0dc5f9efe60a6df4fce55d994","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.5.1.tgz","fileCount":61,"integrity":"sha512-zKeY3Cjbr/aFqPWm6E/L3fxL7V9IZ2/tcCAfxFAyAbfghvZCu0Z1Pa1kCNA1v3NP8w2fWSxtHd06ts+7EL3Mxg==","signatures":[{"sig":"MEYCIQCYafdCtl1veh6rO+7SAhVEYCng/DYU9BBqlF55UpJ8QQIhAKIPtayEX9scmWF6/DKQfsEH90RIKQ0JBt47uqRjggnu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120609},"type":"module","_from":"file:airnauts-comments-server-0.5.1.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./next":{"types":"./dist/next.d.ts","import":"./dist/next.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/a040aabcb56048980ccf49da9d614c35/airnauts-comments-server-0.5.1.tgz","_integrity":"sha512-zKeY3Cjbr/aFqPWm6E/L3fxL7V9IZ2/tcCAfxFAyAbfghvZCu0Z1Pa1kCNA1v3NP8w2fWSxtHd06ts+7EL3Mxg==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.8","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, Next.js).","directories":{},"_nodeVersion":"22.22.3","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.5.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.5.1_1780924736167_0.6269141789240715","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."},"0.6.0":{"name":"@airnauts/comments-server","version":"0.6.0","keywords":["comments","commenting","annotations","feedback","airnauts","server"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.6.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"5cab8c4a6b33b818853b28a36d6dbe4803d6276f","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.6.0.tgz","fileCount":73,"integrity":"sha512-udkUjwArTP8f/0Q24gegSRVxIukv/7hYbCRoPU3gbgf2vNNcHMwDocKAyxmZQVuEA8U1oDii96u/fR9uwmMF4Q==","signatures":[{"sig":"MEUCIQD4fSqHKeL7933Di7OLqNrdpIVz1fWpKZnCe//767qhTQIgBVmCxAR7B2TcNLNMojyXrt81b9ZNvYqQ60jmogJ8HJM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":155828},"type":"module","_from":"file:airnauts-comments-server-0.6.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/6ba53179dc16df05bba64a4836d2d3e7/airnauts-comments-server-0.6.0.tgz","_integrity":"sha512-udkUjwArTP8f/0Q24gegSRVxIukv/7hYbCRoPU3gbgf2vNNcHMwDocKAyxmZQVuEA8U1oDii96u/fR9uwmMF4Q==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.8","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, generic Node bridge).","directories":{},"_nodeVersion":"22.22.3","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.6.0_1781537514856_0.9520571427104114","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."},"0.7.0":{"name":"@airnauts/comments-server","version":"0.7.0","keywords":["comments","commenting","annotations","feedback","airnauts","server"],"author":{"name":"Airnauts"},"license":"MIT","_id":"@airnauts/comments-server@0.7.0","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"homepage":"https://github.com/Airnauts/commenting-tool#readme","bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"dist":{"shasum":"cc2ca92c3ec602f43cb56c41dd4bf188010af6d8","tarball":"https://registry.npmjs.org/@airnauts/comments-server/-/comments-server-0.7.0.tgz","fileCount":73,"integrity":"sha512-n1P1bd/fuGxm2duNI3EtS83DN9X0kaCqo8qi0FnPJXhwByCG51DqJqtTuPaIZSkbN3Bf164FsiRWSTiErK7iTw==","signatures":[{"sig":"MEQCIFM32o6IYWjR0abM6ZtkkBl30ZREN2tCSCLUlL4cZreKAiBaYBGub+OnLcCaZ2Xk/1+RpiAqyuhYZFX7K0R+BPU3OA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":155842},"type":"module","_from":"file:airnauts-comments-server-0.7.0.tgz","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dev":{"types":"./dist/dev.d.ts","import":"./dist/dev.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"}},"scripts":{"test":"vitest run","build":"tsup && tsc --build --force","typecheck":"tsc --build"},"_npmUser":{"name":"mateuszpaulski","email":"mateusz@airnauts.com"},"_resolved":"/tmp/d366a6ee29a43ac86782c024215a82c3/airnauts-comments-server-0.7.0.tgz","_integrity":"sha512-n1P1bd/fuGxm2duNI3EtS83DN9X0kaCqo8qi0FnPJXhwByCG51DqJqtTuPaIZSkbN3Bf164FsiRWSTiErK7iTw==","repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"_npmVersion":"10.9.8","description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, generic Node bridge).","directories":{},"_nodeVersion":"22.22.3","dependencies":{"nanoid":"^5.1.11","@airnauts/comments-core":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@airnauts/comments-test-support":"0.0.0","@airnauts/comments-adapter-memory":"0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/comments-server_0.7.0_1781540305438_0.3323656962687789","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @airnauts/airside-server — install that instead. No longer maintained."}},"time":{"created":"2026-06-02T14:34:51.735Z","modified":"2026-06-16T09:41:13.817Z","0.1.0":"2026-06-02T14:34:52.050Z","0.2.0":"2026-06-08T10:06:05.412Z","0.4.0":"2026-06-08T10:49:47.925Z","0.5.0":"2026-06-08T11:53:41.164Z","0.5.1":"2026-06-08T13:18:56.311Z","0.6.0":"2026-06-15T15:31:54.996Z","0.7.0":"2026-06-15T16:18:25.591Z"},"bugs":{"url":"https://github.com/Airnauts/commenting-tool/issues"},"author":{"name":"Airnauts"},"license":"MIT","homepage":"https://github.com/Airnauts/commenting-tool#readme","keywords":["comments","commenting","annotations","feedback","airnauts","server"],"repository":{"url":"git+https://github.com/Airnauts/commenting-tool.git","type":"git","directory":"packages/server"},"description":"Server runtime for the Airnauts embeddable commenting tool: HTTP router, use-cases, CORS/security, and framework adapters (dev server, generic Node bridge).","maintainers":[{"name":"jkrzemie","email":"hello@airnauts.com"},{"name":"mateuszpaulski","email":"mateusz@airnauts.com"}],"readme":"# @airnauts/comments-server\n\nServer runtime for the [Airnauts commenting tool](https://github.com/Airnauts/commenting-tool): Web-standard `Request → Response` HTTP handler, use cases, CORS/security, and the adapter interfaces for persistence and storage.\n\n## Installation\n\n```bash\npnpm add @airnauts/comments-server\n```\n\n## Quick start\n\n```ts\nimport { createCommentsServer } from '@airnauts/comments-server'\nimport { createMemoryRepository } from '@airnauts/comments-adapter-memory'\nimport { createFileSystemStorage } from '@airnauts/comments-storage-fs'\n\nconst server = createCommentsServer({\n  secretKey: process.env.COMMENTS_SECRET!,\n  projectId: 'my-app',\n  allowedOrigins: ['https://my-app.example.com'],\n  repository: createMemoryRepository(),\n  storage: createFileSystemStorage({ rootDir: './uploads', baseUrl: '/uploads' }),\n})\n\n// server.handle is a Web-standard (Request) => Promise<Response> handler.\n// Mount it in any framework — Next.js, Hono, bare Node http, etc.\n```\n\nFor Next.js (App Router or Pages Router), prefer `@airnauts/comments-next` which wraps the above into single one-call integrations: `createCommentsAppRoute(config)` for the App Router and `createCommentsPagesRoute(config)` for the Pages Router.\n\n## API reference\n\n### `createCommentsServer(options)`\n\nReturns a `CommentsServer` with a single `handle(req: Request): Promise<Response>` method.\n\n#### `CreateCommentsServerOptions`\n\n| Option | Type | Required | Description |\n|---|---|---|---|\n| `secretKey` | `string` | ✓ | Shared bearer token; clients send it as `x-comments-key` |\n| `projectId` | `string` | ✓ | Namespace for all threads in this mount |\n| `allowedOrigins` | `string[]` | ✓ | CORS origin allowlist; requests from other origins get 403 |\n| `repository` | `Repository` | ✓ | Persistence adapter (mongo, postgres, memory, …) |\n| `storage` | `StorageAdapter` | ✓ | File/blob storage adapter |\n| `env` | `string` | | Optional sub-namespace (e.g. `\"staging\"`) within a project |\n| `extensions` | `ServerExtension[]` | | Notification and thread-action plugins; see below |\n| `notifiers` | `Notifier[]` | | **Deprecated** — use `extensions` |\n| `threadParam` | `string` | | URL param for thread deep-links (default `\"comments-thread\"`) |\n| `rateLimit` | `RateLimitConfig \\| false` | | Per-key/IP rate limit; default `{ writesPerMin: 60, readsPerMin: 600 }`; `false` disables |\n| `rateLimiter` | `RateLimiter` | | Override the rate-limiter implementation |\n| `uploads` | `{ maxBytes?: number }` | | Per-upload size cap (default 5 MB) |\n| `extractIp` | `(req: Request) => string` | | Override IP extraction (default: first hop of `x-forwarded-for`) |\n\n### Extensions (`ServerExtension`)\n\nExtensions come in two kinds, both passed to `extensions: [...]`.\n\n**Notification extensions** (`NotificationExtension`) receive a `NotificationEvent` after each write (thread created or comment added). Failures are isolated — they never break the write.\n\n```ts\nimport { slackExtension } from '@airnauts/comments-notifier-slack'\nimport { emailExtension } from '@airnauts/comments-notifier-email'\n\ncreateCommentsServer({\n  // ...\n  extensions: [\n    ...slackExtension({ webhookUrl: process.env.SLACK_WEBHOOK! }),\n    ...emailExtension({ transport, from: 'noreply@acme.com' }),\n  ],\n})\n```\n\n**Thread-action extensions** (`ThreadActionExtension`) add reviewer-triggered actions to the thread toolbar (e.g. \"Create Jira issue\"). Each action declares an `id`, `label`, `slot`, optional `visibleWhen` predicate, and a `run` handler that may persist an `externalLink` back on the thread.\n\n```ts\nimport { jiraExtension } from '@airnauts/comments-integration-jira'\n\ncreateCommentsServer({\n  // ...\n  extensions: jiraExtension({ siteUrl: '...', email: '...', apiToken: '...', projectKey: 'PROJ' }),\n})\n```\n\n### Adapter interfaces\n\nThe types below are what custom adapters must implement:\n\n```ts\nimport type { Repository, StorageAdapter } from '@airnauts/comments-server'\n```\n\n**`Repository`** — persistence; implement `createThread`, `getThread`, `listThreads`, `addComment`, `setStatus`, `updateAnchor`, `upsertExternalLink`, `putAttachment`, `getAttachments`.\n\n**`StorageAdapter`** — file storage; implement `put(blob: PutBlob): Promise<PutResult>`.\n\nOther exported types: `NewThread`, `NewComment`, `AnchorPatch`, `ListQuery`, `ListResult`, `Scope`, `PutBlob`, `PutResult`. Utility functions: `readAllBytes`, `sanitizeName`.\n\n### `lazyRepository(connect, opts?)`\n\nWraps a `() => Promise<Repository>` factory so it connects lazily on first use and optionally memoizes the connection under a `cacheKey` (useful for hot-reload / warm serverless environments).\n\n### Rate limiting\n\n`InMemoryRateLimiter` is exported for use with the `rateLimiter` option or in tests. Implement the `RateLimiter` interface to plug in Redis or any other store.\n\n### Error classes\n\n`AuthInvalidKeyError`, `ConflictError`, `NotFoundError`, `OriginNotAllowedError`, `RateLimitedError`, `UploadTooLargeError`, `ValidationError`, `DomainError`, `IntegrationError`, `toResponse`.\n\n## Subpath exports\n\n### `@airnauts/comments-server/node`\n\nGeneric Node↔Web bridge for mounting the server on any Node host (Express, bare `node:http`, etc.). Usually consumed via `@airnauts/comments-next` for Next.js hosts.\n\n```ts\nimport { nodeRequestToWeb, webToNode } from '@airnauts/comments-server/node'\n\n// In an Express/http handler — bridge the Node req/res to the Web standard:\napp.use('/api/comments', async (req, res) => {\n  const url = new URL(req.url, `http://${req.headers.host}`)\n  const webRes = await server.handle(await nodeRequestToWeb(req, url))\n  await webToNode(webRes, res)\n})\n```\n\n### `@airnauts/comments-server/dev`\n\nMinimal Node `http` server that bridges Web `Request/Response` — for local development of non-Next.js consumers.\n\n```ts\nimport { createDevServer } from '@airnauts/comments-server/dev'\n\nconst dev = createDevServer((req) => server.handle(req), { port: 4321 })\nconst { port } = await dev.listen()\n// dev.close() to shut down\n```\n\n## Requirements\n\n- Node.js ≥ 18 (Web `Request`/`Response` are built in)\n\n## Related packages\n\n- **`@airnauts/comments-next`** — one-call Next.js App and Pages Router integration (`createCommentsAppRoute` / `createCommentsPagesRoute`)\n- **`@airnauts/comments-adapter-mongo`** — MongoDB repository\n- **`@airnauts/comments-adapter-postgres`** — PostgreSQL repository\n- **`@airnauts/comments-adapter-memory`** — in-memory repository for dev/tests\n- **`@airnauts/comments-storage-vercel-blob`** — Vercel Blob storage\n- **`@airnauts/comments-storage-fs`** — filesystem storage\n- **`@airnauts/comments-notifier-slack`** — Slack notification extension\n- **`@airnauts/comments-notifier-email`** — email notification extension\n- **`@airnauts/comments-integration-jira`** — Jira thread-action extension\n- **`@airnauts/comments-core`** — shared types and schemas (consumed transitively)\n\nSee [docs/architecture.md](https://github.com/Airnauts/commenting-tool/blob/main/docs/architecture.md) and the [integration guide](https://github.com/Airnauts/commenting-tool/blob/main/docs/integration.md).\n\n## License\n\nMIT © Airnauts\n","readmeFilename":"README.md"}