{"_id":"@allmightypush/push-express","name":"@allmightypush/push-express","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@allmightypush/push-express","version":"1.0.0","description":"Express middleware for push notification library","main":"dist/cjs/index.js","module":"dist/esm/index.js","types":"dist/types/index.d.ts","exports":{".":{"require":"./dist/cjs/index.js","import":"./dist/esm/index.js","types":"./dist/types/index.d.ts"}},"scripts":{"build":"npm run build:cjs && npm run build:esm && npm run build:types","build:cjs":"tsc -p tsconfig.cjs.json","build:esm":"tsc -p tsconfig.esm.json","build:types":"tsc -p tsconfig.types.json","test":"jest --passWithNoTests","test:watch":"jest --watch","test:coverage":"jest --coverage --passWithNoTests","clean":"rm -rf dist"},"keywords":["push","notification","express","middleware"],"author":{"name":"Samtes64"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Samtes64/all-mighty-push.git","directory":"packages/push-express"},"bugs":{"url":"https://github.com/Samtes64/all-mighty-push/issues"},"homepage":"https://github.com/Samtes64/all-mighty-push/tree/main/packages/push-express#readme","dependencies":{"@allmightypush/push-core":"^1.0.0"},"peerDependencies":{"express":"^4.18.0 || ^5.0.0"},"devDependencies":{"@types/express":"^4.17.21","@types/supertest":"^6.0.2","express":"^4.18.2","supertest":"^6.3.3"},"engines":{"node":">=16.0.0"},"_id":"@allmightypush/push-express@1.0.0","gitHead":"8d7b012f519f95515344d9b5c96d4ba42039046b","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-ZfowcZAUiH+q7i4ijFxFU4uqI/yGEbNdg8VKN94MIUlyo9PInvC2cabXquzdRJpD/Hm984D94siQjJiTHvqrRg==","shasum":"0bb2046982a1ee01650ce17bd16d14af7faa1e0f","tarball":"https://registry.npmjs.org/@allmightypush/push-express/-/push-express-1.0.0.tgz","fileCount":8,"unpackedSize":27763,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICSh77gXaazv1yy1M+jTjNkwkZmjM4agAefgvK1+B0uoAiEA7N/bbd8N1ySN8WHjbah5AErwfv/f+kwQ1ugK1ViAEjo="}]},"_npmUser":{"name":"samtes64","email":"samtes64@gmail.com"},"directories":{},"maintainers":[{"name":"samtes64","email":"samtes64@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/push-express_1.0.0_1768561597609_0.03301642561611695"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-16T11:06:37.522Z","1.0.0":"2026-01-16T11:06:37.746Z","modified":"2026-01-16T11:06:37.967Z"},"maintainers":[{"name":"samtes64","email":"samtes64@gmail.com"}],"description":"Express middleware for push notification library","homepage":"https://github.com/Samtes64/all-mighty-push/tree/main/packages/push-express#readme","keywords":["push","notification","express","middleware"],"repository":{"type":"git","url":"git+https://github.com/Samtes64/all-mighty-push.git","directory":"packages/push-express"},"author":{"name":"Samtes64"},"bugs":{"url":"https://github.com/Samtes64/all-mighty-push/issues"},"license":"MIT","readme":"# @allmightypush/push-express\n\nExpress middleware for managing push notification subscriptions.\n\n## Installation\n\n```bash\nnpm install @allmightypush/push-express @allmightypush/push-core express\n```\n\n## Quick Start\n\n```typescript\nimport express from 'express';\nimport { createExpressMiddleware } from '@allmightypush/push-express';\nimport { SQLiteStorageAdapter } from '@allmightypush/push-storage-sqlite';\n\nconst app = express();\nconst storage = new SQLiteStorageAdapter({ filename: './push.db' });\n\napp.use(express.json());\napp.use('/api/push', createExpressMiddleware({ storageAdapter: storage }));\n\napp.listen(3000, () => {\n  console.log('Server running on port 3000');\n});\n```\n\n## API Endpoints\n\n### POST /subscriptions\n\nCreate a new push notification subscription.\n\n**Request Body:**\n```json\n{\n  \"endpoint\": \"https://fcm.googleapis.com/fcm/send/...\",\n  \"keys\": {\n    \"p256dh\": \"user-public-key\",\n    \"auth\": \"user-auth-secret\"\n  },\n  \"userId\": \"optional-user-id\",\n  \"metadata\": {\n    \"deviceType\": \"mobile\",\n    \"appVersion\": \"1.0.0\"\n  }\n}\n```\n\n**Response:** `201 Created`\n```json\n{\n  \"id\": \"subscription-id\",\n  \"endpoint\": \"https://fcm.googleapis.com/fcm/send/...\",\n  \"keys\": { \"p256dh\": \"...\", \"auth\": \"...\" },\n  \"userId\": \"optional-user-id\",\n  \"status\": \"active\",\n  \"createdAt\": \"2024-01-01T00:00:00.000Z\",\n  \"updatedAt\": \"2024-01-01T00:00:00.000Z\"\n}\n```\n\n### GET /subscriptions/:id\n\nRetrieve a subscription by ID.\n\n**Response:** `200 OK` or `404 Not Found`\n\n### GET /subscriptions\n\nList subscriptions with optional filtering and pagination.\n\n**Query Parameters:**\n- `userId` - Filter by user ID\n- `status` - Filter by status (active, expired, failed)\n- `limit` - Maximum results (default: 100)\n- `offset` - Pagination offset (default: 0)\n\n**Response:** `200 OK`\n```json\n{\n  \"subscriptions\": [...],\n  \"total\": 10,\n  \"limit\": 100,\n  \"offset\": 0\n}\n```\n\n### PATCH /subscriptions/:id\n\nUpdate a subscription.\n\n**Request Body:**\n```json\n{\n  \"status\": \"expired\",\n  \"metadata\": { \"updated\": true }\n}\n```\n\n**Response:** `200 OK` or `404 Not Found`\n\n### DELETE /subscriptions/:id\n\nDelete a subscription.\n\n**Response:** `204 No Content` or `404 Not Found`\n\n## Configuration Options\n\n```typescript\ninterface ExpressMiddlewareOptions {\n  // Storage adapter for managing subscriptions (required)\n  storageAdapter: StorageAdapter;\n\n  // Optional authentication middleware\n  authMiddleware?: (req, res, next) => void;\n\n  // Custom base path (default: '')\n  basePath?: string;\n\n  // Custom validation function\n  validateSubscription?: (subscription) => Promise<void> | void;\n}\n```\n\n## Examples\n\n### With Authentication\n\n```typescript\nimport { createExpressMiddleware } from '@allmightypush/push-express';\n\nconst authMiddleware = (req, res, next) => {\n  const token = req.headers.authorization?.replace('Bearer ', '');\n  \n  if (!token || !isValidToken(token)) {\n    return res.status(401).json({ error: 'Unauthorized' });\n  }\n  \n  next();\n};\n\napp.use('/api/push', createExpressMiddleware({\n  storageAdapter: storage,\n  authMiddleware,\n}));\n```\n\n### With Custom Validation\n\n```typescript\napp.use('/api/push', createExpressMiddleware({\n  storageAdapter: storage,\n  validateSubscription: async (data) => {\n    // Ensure endpoint uses HTTPS\n    if (!data.endpoint?.startsWith('https://')) {\n      throw new Error('Endpoint must use HTTPS');\n    }\n    \n    // Check against allowed domains\n    const url = new URL(data.endpoint);\n    if (!allowedDomains.includes(url.hostname)) {\n      throw new Error('Endpoint domain not allowed');\n    }\n  },\n}));\n```\n\n### With Custom Base Path\n\n```typescript\napp.use('/api/push', createExpressMiddleware({\n  storageAdapter: storage,\n  basePath: '/v1', // Routes will be /api/push/v1/subscriptions\n}));\n```\n\n## Error Handling\n\nThe middleware returns appropriate HTTP status codes:\n\n- `200 OK` - Successful GET/PATCH\n- `201 Created` - Successful POST\n- `204 No Content` - Successful DELETE\n- `400 Bad Request` - Invalid input\n- `401 Unauthorized` - Authentication failed (if auth middleware used)\n- `404 Not Found` - Resource not found\n- `500 Internal Server Error` - Server error\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-ab754cb87cb9b36600c1ff6af4ed091b"}