{"_id":"@abbacchio/sqlite-api","name":"@abbacchio/sqlite-api","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.4":{"name":"@abbacchio/sqlite-api","version":"0.1.4","description":"SQLite-backed log storage API - receive and query logs via HTTP","type":"module","main":"dist/server.js","types":"dist/server.d.ts","exports":{".":{"types":"./dist/server.d.ts","default":"./dist/server.js"}},"bin":{"abbacchio-sqlite":"dist/server.js"},"scripts":{"dev":"tsx watch src/server.ts","build":"tsc","start":"node dist/server.js","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/mood-agency/abbacchio.git","directory":"packages/sqlite-api"},"keywords":["logs","logging","sqlite","storage","api","server","pino","winston","bunyan"],"author":"","license":"MIT","dependencies":{"@hono/node-server":"^1.13.7","better-sqlite3":"^11.7.0","dotenv":"^17.2.3","hono":"^4.6.14","nanoid":"^5.0.9"},"devDependencies":{"@types/better-sqlite3":"^7.6.12","@types/node":"^22.10.5","tsx":"^4.19.2","typescript":"^5.7.2"},"engines":{"node":">=18"},"_id":"@abbacchio/sqlite-api@0.1.4","gitHead":"6f1c4f9d756c538bf61060c1785b3d4209ca4cec","bugs":{"url":"https://github.com/mood-agency/abbacchio/issues"},"homepage":"https://github.com/mood-agency/abbacchio#readme","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-kBr9xbRCwGYAZSHsCbr0q09ne9D4nlbRVbyc6sKE/XG7EiPYtwu7JR6i+dO0eiM5QNLF+eWaeo+EB4lyjThkOw==","shasum":"9ac9feba2dbae6c46860fa8f7b7b8994727a1219","tarball":"https://registry.npmjs.org/@abbacchio/sqlite-api/-/sqlite-api-0.1.4.tgz","fileCount":34,"unpackedSize":77741,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHSw59yQY6G1X9AiTZnyGpre7/LtgKauj+42jFQ7qZbMAiEA8E8ORxM6/ie/qw29HwtuBzgDPc0J4OsgWwtjTOP9TCw="}]},"_npmUser":{"name":"argenisleon","email":"argenisleon@gmail.com"},"directories":{},"maintainers":[{"name":"argenisleon","email":"argenisleon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sqlite-api_0.1.4_1771532394350_0.1609652387461904"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-19T20:19:54.258Z","0.1.4":"2026-02-19T20:19:54.501Z","modified":"2026-02-19T20:19:54.738Z"},"maintainers":[{"name":"argenisleon","email":"argenisleon@gmail.com"}],"description":"SQLite-backed log storage API - receive and query logs via HTTP","homepage":"https://github.com/mood-agency/abbacchio#readme","keywords":["logs","logging","sqlite","storage","api","server","pino","winston","bunyan"],"repository":{"type":"git","url":"git+https://github.com/mood-agency/abbacchio.git","directory":"packages/sqlite-api"},"bugs":{"url":"https://github.com/mood-agency/abbacchio/issues"},"license":"MIT","readme":"# @abbacchio/sqlite-api\r\n\r\nSQLite-backed log storage API for [Abbacchio](https://github.com/mood-agency/abbacchio). Receives logs via HTTP and persists them in SQLite for later querying by other services.\r\n\r\nCompatible with all Abbacchio transports (Pino, Winston, Bunyan, Console).\r\n\r\n## Features\r\n\r\n- **SQLite Persistence**: Logs stored on disk with WAL mode for performance\r\n- **Compatible API**: Same ingestion endpoint as `@abbacchio/api` - transports work without changes\r\n- **Query & Filter**: Search logs by channel, level, text, time range with pagination\r\n- **Auto-Prune**: Configurable max log count to prevent unbounded growth\r\n- **Production Ready**: Rate limiting, API key auth, input validation, graceful shutdown\r\n- **CLI Executable**: Run directly with `npx abbacchio-sqlite`\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @abbacchio/sqlite-api\r\n# or\r\npnpm add @abbacchio/sqlite-api\r\n```\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# Start the server\r\nnpx abbacchio-sqlite\r\n\r\n# Or with environment variables\r\nPORT=4002 SQLITE_PATH=./logs.db npx abbacchio-sqlite\r\n```\r\n\r\nSend a test log:\r\n\r\n```bash\r\ncurl -X POST http://localhost:4002/api/logs \\\r\n  -H \"Content-Type: application/json\" \\\r\n  -d '{\"level\": 30, \"msg\": \"Hello world\"}'\r\n```\r\n\r\nQuery it back:\r\n\r\n```bash\r\ncurl http://localhost:4002/api/logs\r\n```\r\n\r\n## API Endpoints\r\n\r\n| Method | Endpoint | Description |\r\n|--------|----------|-------------|\r\n| `POST` | `/api/logs` | Ingest single or batch logs |\r\n| `GET` | `/api/logs` | Query logs with filters and pagination |\r\n| `DELETE` | `/api/logs` | Clear logs (all or by channel) |\r\n| `GET` | `/api/channels` | List registered channels |\r\n| `GET` | `/api/stats` | Database statistics |\r\n| `GET` | `/api/generate-key` | Generate encryption key |\r\n| `GET` | `/health` | Health check |\r\n\r\n### Log Ingestion\r\n\r\n**Single log:**\r\n```bash\r\ncurl -X POST http://localhost:4002/api/logs \\\r\n  -H \"Content-Type: application/json\" \\\r\n  -H \"X-Channel: my-app\" \\\r\n  -d '{\"level\": 30, \"msg\": \"User logged in\", \"userId\": 123}'\r\n```\r\n\r\n**Batch logs:**\r\n```bash\r\ncurl -X POST http://localhost:4002/api/logs \\\r\n  -H \"Content-Type: application/json\" \\\r\n  -d '{\r\n    \"logs\": [\r\n      {\"level\": 30, \"msg\": \"Request started\"},\r\n      {\"level\": 50, \"msg\": \"Something failed\"}\r\n    ]\r\n  }'\r\n```\r\n\r\n### Querying Logs\r\n\r\n```bash\r\n# All logs (newest first, default limit 100)\r\ncurl http://localhost:4002/api/logs\r\n\r\n# Filter by channel\r\ncurl \"http://localhost:4002/api/logs?channel=my-app\"\r\n\r\n# Filter by minimum level (40 = warn and above)\r\ncurl \"http://localhost:4002/api/logs?level=40\"\r\n\r\n# Search in message text\r\ncurl \"http://localhost:4002/api/logs?search=error\"\r\n\r\n# Time range (unix timestamps in ms)\r\ncurl \"http://localhost:4002/api/logs?since=1700000000000&until=1700100000000\"\r\n\r\n# Pagination\r\ncurl \"http://localhost:4002/api/logs?limit=50&offset=100\"\r\n\r\n# Oldest first\r\ncurl \"http://localhost:4002/api/logs?order=asc\"\r\n\r\n# Combine filters\r\ncurl \"http://localhost:4002/api/logs?channel=my-app&level=40&search=timeout&limit=20\"\r\n```\r\n\r\n**Query Parameters:**\r\n\r\n| Parameter | Type | Default | Description |\r\n|-----------|------|---------|-------------|\r\n| `channel` | string | - | Filter by channel name |\r\n| `level` | number | - | Minimum log level (10=trace, 20=debug, 30=info, 40=warn, 50=error, 60=fatal) |\r\n| `search` | string | - | Search text in message (case-insensitive) |\r\n| `limit` | number | `100` | Results per page (max 1000) |\r\n| `offset` | number | `0` | Pagination offset |\r\n| `since` | number | - | Start timestamp in ms |\r\n| `until` | number | - | End timestamp in ms |\r\n| `order` | string | `desc` | Sort order: `asc` or `desc` |\r\n\r\n**Response:**\r\n```json\r\n{\r\n  \"logs\": [\r\n    {\r\n      \"id\": \"abc123\",\r\n      \"level\": 30,\r\n      \"levelLabel\": \"info\",\r\n      \"time\": 1700000000000,\r\n      \"msg\": \"User logged in\",\r\n      \"channel\": \"my-app\",\r\n      \"data\": { \"userId\": 123 }\r\n    }\r\n  ],\r\n  \"count\": 1,\r\n  \"total\": 5000,\r\n  \"limit\": 100,\r\n  \"offset\": 0\r\n}\r\n```\r\n\r\n## Using with Transports\r\n\r\nThe ingestion endpoint is compatible with `@abbacchio/transport`. Just point to this server's URL:\r\n\r\n```typescript\r\nimport pino from \"pino\";\r\n\r\nconst logger = pino({\r\n  transport: {\r\n    target: \"@abbacchio/transport/transports/pino\",\r\n    options: {\r\n      url: \"http://localhost:4002/api/logs\",\r\n      channel: \"my-app\",\r\n    },\r\n  },\r\n});\r\n\r\nlogger.info(\"This log is persisted in SQLite\");\r\n```\r\n\r\n## Configuration\r\n\r\n| Variable | Default | Description |\r\n|----------|---------|-------------|\r\n| `PORT` | `4002` | Server port |\r\n| `SQLITE_PATH` | `./data/logs.db` | SQLite database file path |\r\n| `SQLITE_WAL` | `true` | Enable WAL mode for better write performance |\r\n| `SQLITE_MAX_LOGS` | `100000` | Max logs before auto-prune (0 = unlimited) |\r\n| `API_KEY` | - | API key for authentication |\r\n| `CORS_ORIGIN` | `*` (dev) | Allowed CORS origins |\r\n| `ENABLE_RATE_LIMIT` | `true` | Enable rate limiting |\r\n| `RATE_LIMIT_WINDOW` | `60000` | Rate limit window in ms |\r\n| `RATE_LIMIT_MAX` | `1000` | Max requests per window |\r\n| `MAX_PAYLOAD_SIZE` | `1048576` | Max payload size (1MB) |\r\n| `MAX_BATCH_SIZE` | `1000` | Max logs per batch |\r\n| `TRUST_PROXY` | `false` | Trust proxy headers for IP detection |\r\n| `SHUTDOWN_TIMEOUT` | `30000` | Graceful shutdown timeout in ms |\r\n\r\n## Statistics\r\n\r\n```bash\r\ncurl http://localhost:4002/api/stats\r\n```\r\n\r\n```json\r\n{\r\n  \"totalLogs\": 5000,\r\n  \"dbSizeBytes\": 2097152,\r\n  \"channels\": [\r\n    { \"name\": \"my-app\", \"count\": 3000, \"lastActivity\": 1700000000000 },\r\n    { \"name\": \"default\", \"count\": 2000, \"lastActivity\": 1699999000000 }\r\n  ]\r\n}\r\n```\r\n\r\n## Health Check\r\n\r\n```bash\r\ncurl http://localhost:4002/health\r\n```\r\n\r\n```json\r\n{\r\n  \"status\": \"ok\",\r\n  \"uptime\": 3600.5,\r\n  \"totalLogs\": 5000,\r\n  \"dbSizeBytes\": 2097152,\r\n  \"channels\": 2\r\n}\r\n```\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md","_rev":"1-eb02faea5a87207ae51162321fe853b8"}