{"_id":"@amitpatel-wstf/cors","_rev":"2-8e9e1b30fac47e2edcf3b2bf6eaac410","name":"@amitpatel-wstf/cors","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@amitpatel-wstf/cors","version":"1.0.0","keywords":["cors","express","connect","middleware","typescript","cross-origin","http"],"author":{"name":"Amit Patel"},"license":"MIT","_id":"@amitpatel-wstf/cors@1.0.0","maintainers":[{"name":"amitpatel-wstf","email":"amit.patel@thewasserstoff.com"}],"homepage":"https://github.com/amitpatel-wstf/cors#readme","bugs":{"url":"https://github.com/amitpatel-wstf/cors/issues"},"dist":{"shasum":"b401fd80d74c435612d2a52d5325a3756d82acd9","tarball":"https://registry.npmjs.org/@amitpatel-wstf/cors/-/cors-1.0.0.tgz","fileCount":7,"integrity":"sha512-wPxkTpjQEH6FDxuWB0mJQ7HiDuRn5RNLjFPnq3aOcZBVlYffmUQpNfRoih6i23aCcStyRIhXaj201TamLO0COg==","signatures":[{"sig":"MEQCIBPoZQn77XFzz23giQelgli/UENPI1sbAOWsRLqAnhQjAiBykpY73s3w1DdbeT3bgHz5LZLmT1O3X1Q+L27yu8T5JQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35181},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=14.0.0"},"gitHead":"4f2c6ca4358bdb3080aa9870248f161a40fd74b1","scripts":{"dev":"tsc --watch","lint":"eslint src/**/*.ts","test":"jest","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"amitpatel-wstf","email":"amit.patel@thewasserstoff.com"},"repository":{"url":"git+https://github.com/amitpatel-wstf/cors.git","type":"git"},"_npmVersion":"10.9.3","description":"Node.js CORS middleware with TypeScript support","directories":{},"_nodeVersion":"22.20.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.3.3","@types/jest":"^30.0.0","@types/node":"^20.19.19","@types/mocha":"^10.0.10","@types/connect":"^3.4.38","@types/express":"^4.17.21"},"peerDependencies":{"express":"^4.0.0 || ^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/cors_1.0.0_1759772182502_0.6666056706983887","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@amitpatel-wstf/cors","version":"1.0.2","description":"Node.js CORS middleware with TypeScript support","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc && npm run minify","build:clean":"rm -rf dist && npm run build","minify":"terser dist/index.js -o dist/index.js -c -m --comments false","dev":"tsc --watch","prepublishOnly":"npm run build:clean","test":"tsc --noEmit && echo 'Type checking passed ✓'","test:unit":"node --test tests/cors.test.ts","size":"npm pack --dry-run"},"keywords":["cors","express","connect","middleware","typescript","cross-origin","http"],"author":{"name":"Amit Patel"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/amitpatel-wstf/cors.git"},"sideEffects":false,"devDependencies":{"@types/connect":"^3.4.38","@types/express":"^4.17.21","@types/jest":"^30.0.0","@types/mocha":"^10.0.10","@types/node":"^20.19.19","terser":"^5.44.0","typescript":"^5.3.3"},"peerDependencies":{"express":"^4.0.0 || ^5.0.0"},"engines":{"node":">=14.0.0"},"_id":"@amitpatel-wstf/cors@1.0.2","gitHead":"4f2c6ca4358bdb3080aa9870248f161a40fd74b1","bugs":{"url":"https://github.com/amitpatel-wstf/cors/issues"},"homepage":"https://github.com/amitpatel-wstf/cors#readme","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-rQSWaPKK8k+diMtLKf6wG8ytBVm1SYDwAQPTtUtLQKEFYroFZSWor8fgkIhAwAkKPuiXEOji2bEagprETZsjoQ==","shasum":"7024bdca6b4eeafe473a0428298f3b13eaa465e3","tarball":"https://registry.npmjs.org/@amitpatel-wstf/cors/-/cors-1.0.2.tgz","fileCount":5,"unpackedSize":15272,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDlYtUdMYyz7aHwYGh1agByRsjlv9CG1DxgYYlhsBI1KAiEAm0UCnRO2o9FSS0AbJou8O6y32olZGHpqY6SEpMpCCMY="}]},"_npmUser":{"name":"amitpatel-wstf","email":"amit.patel@thewasserstoff.com"},"directories":{},"maintainers":[{"name":"amitpatel-wstf","email":"amit.patel@thewasserstoff.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cors_1.0.2_1759774118120_0.9631659981270797"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-06T17:36:22.406Z","modified":"2025-10-06T18:08:38.525Z","1.0.0":"2025-10-06T17:36:22.740Z","1.0.2":"2025-10-06T18:08:38.327Z"},"bugs":{"url":"https://github.com/amitpatel-wstf/cors/issues"},"author":{"name":"Amit Patel"},"license":"MIT","homepage":"https://github.com/amitpatel-wstf/cors#readme","keywords":["cors","express","connect","middleware","typescript","cross-origin","http"],"repository":{"type":"git","url":"git+https://github.com/amitpatel-wstf/cors.git"},"description":"Node.js CORS middleware with TypeScript support","maintainers":[{"name":"amitpatel-wstf","email":"amit.patel@thewasserstoff.com"}],"readme":"# CORS Middleware\n\nA flexible and feature-rich CORS (Cross-Origin Resource Sharing) middleware for Node.js with full TypeScript support. This middleware enables you to configure CORS with various options for Express and Connect-based applications.\n\n## Features\n\n- 🪶 **Lightweight**: Only 2.9 KB minified, ~1.2 KB gzipped\n- 🚀 Simple and easy to use\n- 🔒 Secure by default\n- 🎯 Flexible origin validation (string, array, RegExp, function)\n- ⚡ Dynamic CORS configuration per request\n- 📝 Full TypeScript support with type definitions\n- 🧪 Comprehensive test coverage\n- 🔧 Highly configurable\n- 🌐 Support for preflight requests\n- 📦 Zero runtime dependencies (peer dependency on Express)\n- 🌲 Tree-shakeable for optimal bundle size\n\n## Installation\n\n```bash\nnpm install @amitpatel-wstf/cors\n```\n\n**Package Size**: 5.4 KB (gzipped) | 15 KB (unpacked) | 2.9 KB (minified JS)\n\n## Quick Start\n\n### Enable CORS for all routes\n\n```typescript\nimport express from 'express';\nimport cors from '@amitpatel-wstf/cors';\n\nconst app = express();\n\n// Enable CORS for all routes with default settings\napp.use(cors());\n\napp.get('/api/data', (req, res) => {\n  res.json({ message: 'CORS enabled!' });\n});\n\napp.listen(3000);\n```\n\n### Enable CORS for a single route\n\n```typescript\napp.get('/api/products/:id', cors(), (req, res) => {\n  res.json({ product: 'Product details' });\n});\n```\n\n## Configuration Options\n\n### CorsOptions Interface\n\n```typescript\ninterface CorsOptions {\n  // Configures the Access-Control-Allow-Origin header\n  origin?: boolean | string | RegExp | (string | RegExp)[] | OriginCallback;\n  \n  // Configures the Access-Control-Allow-Methods header\n  methods?: string | string[];\n  \n  // Configures the Access-Control-Allow-Headers header\n  allowedHeaders?: string | string[];\n  \n  // Configures the Access-Control-Expose-Headers header\n  exposedHeaders?: string | string[];\n  \n  // Configures the Access-Control-Allow-Credentials header\n  credentials?: boolean;\n  \n  // Configures the Access-Control-Max-Age header\n  maxAge?: number;\n  \n  // Pass the CORS preflight response to the next handler\n  preflightContinue?: boolean;\n  \n  // Status code for successful OPTIONS requests\n  optionsSuccessStatus?: number;\n}\n```\n\n### Default Configuration\n\n```typescript\n{\n  origin: '*',\n  methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n  preflightContinue: false,\n  optionsSuccessStatus: 204\n}\n```\n\n## Usage Examples\n\n### 1. Allow Specific Origin\n\n```typescript\nconst corsOptions = {\n  origin: 'http://example.com',\n  optionsSuccessStatus: 200\n};\n\napp.use(cors(corsOptions));\n```\n\n### 2. Allow Multiple Origins\n\n```typescript\nconst corsOptions = {\n  origin: [\n    'http://localhost:3000',\n    'http://example.com',\n    'http://example2.com'\n  ],\n  credentials: true\n};\n\napp.use(cors(corsOptions));\n```\n\n### 3. Dynamic Origin Validation\n\n```typescript\nconst corsOptions = {\n  origin: (origin, callback) => {\n    const allowedOrigins = ['http://localhost:3000', 'http://example.com'];\n    \n    if (!origin || allowedOrigins.includes(origin)) {\n      callback(null, true);\n    } else {\n      callback(new Error('Not allowed by CORS'));\n    }\n  }\n};\n\napp.use(cors(corsOptions));\n```\n\n### 4. Using RegExp for Origin Matching\n\n```typescript\nconst corsOptions = {\n  origin: /example\\.com$/  // Allows all subdomains of example.com\n};\n\napp.use(cors(corsOptions));\n```\n\n### 5. Custom Headers and Credentials\n\n```typescript\nconst corsOptions = {\n  origin: 'http://localhost:3000',\n  methods: ['GET', 'POST', 'PUT', 'DELETE'],\n  allowedHeaders: ['Content-Type', 'Authorization', 'X-Custom-Header'],\n  exposedHeaders: ['X-Total-Count', 'X-Response-Time'],\n  credentials: true,\n  maxAge: 86400  // 24 hours\n};\n\napp.use(cors(corsOptions));\n```\n\n### 6. Enable Pre-flight for Specific Routes\n\n```typescript\n// Enable pre-flight\napp.options('/api/complex', cors());\n\n// Handle the actual request\napp.delete('/api/complex', cors(), (req, res) => {\n  res.json({ message: 'DELETE request with CORS' });\n});\n```\n\n### 7. Enable Pre-flight Across All Routes\n\n```typescript\napp.options('*', cors());\n```\n\n### 8. Dynamic CORS Options Based on Request\n\n```typescript\nconst corsOptionsDelegate = (req, callback) => {\n  let corsOptions;\n  \n  if (req.path.startsWith('/api/auth')) {\n    corsOptions = {\n      origin: 'http://trusted-domain.com',\n      credentials: true\n    };\n  } else if (req.path.startsWith('/api/public')) {\n    corsOptions = {\n      origin: '*'\n    };\n  } else {\n    corsOptions = {\n      origin: ['http://localhost:3000', 'http://example.com']\n    };\n  }\n  \n  callback(null, corsOptions);\n};\n\napp.use('/api', cors(corsOptionsDelegate));\n```\n\n### 9. Continue to Next Handler After Preflight\n\n```typescript\nconst corsOptions = {\n  preflightContinue: true,\n  optionsSuccessStatus: 204\n};\n\napp.options('/api/continue', cors(corsOptions), (req, res) => {\n  // Custom OPTIONS handler\n  res.setHeader('X-Custom-Header', 'value');\n  res.sendStatus(204);\n});\n```\n\n### 10. Async Origin Validation\n\n```typescript\nconst corsOptions = {\n  origin: async (origin, callback) => {\n    try {\n      // Simulate async database call\n      const allowedOrigins = await fetchAllowedOriginsFromDB();\n      \n      if (!origin || allowedOrigins.includes(origin)) {\n        callback(null, true);\n      } else {\n        callback(null, false);\n      }\n    } catch (error) {\n      callback(error, false);\n    }\n  }\n};\n\napp.use(cors(corsOptions));\n```\n\n## Configuration Details\n\n### origin\n\nConfigures the `Access-Control-Allow-Origin` CORS header.\n\n- `boolean`: Set to `true` to reflect the request origin, or `false` to disable CORS\n- `string`: Set to a specific origin (e.g., `'http://example.com'`)\n- `RegExp`: Set to a regular expression to match origins (e.g., `/example\\.com$/`)\n- `Array`: Set to an array of valid origins (strings or RegExp)\n- `Function`: Custom function for dynamic origin validation\n\n**Default:** `'*'`\n\n### methods\n\nConfigures the `Access-Control-Allow-Methods` CORS header.\n\n- `string`: Comma-separated list of methods (e.g., `'GET,POST'`)\n- `Array`: Array of method strings (e.g., `['GET', 'POST', 'PUT']`)\n\n**Default:** `'GET,HEAD,PUT,PATCH,POST,DELETE'`\n\n### allowedHeaders\n\nConfigures the `Access-Control-Allow-Headers` CORS header.\n\n- `string`: Comma-separated list of headers\n- `Array`: Array of header strings\n- If not specified, defaults to reflecting the headers specified in the request's `Access-Control-Request-Headers` header\n\n### exposedHeaders\n\nConfigures the `Access-Control-Expose-Headers` CORS header.\n\n- `string`: Comma-separated list of headers\n- `Array`: Array of header strings\n\n### credentials\n\nConfigures the `Access-Control-Allow-Credentials` CORS header.\n\n- `boolean`: Set to `true` to pass the header, otherwise it is omitted\n\n**Default:** `false`\n\n### maxAge\n\nConfigures the `Access-Control-Max-Age` CORS header.\n\n- `number`: Maximum number of seconds the results can be cached\n\n### preflightContinue\n\nPass the CORS preflight response to the next handler.\n\n- `boolean`: Set to `true` to pass to next handler, `false` to end the response\n\n**Default:** `false`\n\n### optionsSuccessStatus\n\nProvides a status code to use for successful `OPTIONS` requests.\n\n- `number`: HTTP status code (some legacy browsers choke on `204`)\n\n**Default:** `204`\n\n## How It Works\n\n### Simple Requests\n\nFor simple requests (GET, HEAD, POST with simple headers), the middleware:\n1. Validates the origin\n2. Sets appropriate CORS headers\n3. Calls the next middleware\n\n### Preflight Requests\n\nFor preflight requests (OPTIONS method), the middleware:\n1. Validates the origin\n2. Sets all CORS headers including allowed methods and headers\n3. Either ends the response with the configured status code or passes to the next handler\n\n## Security Considerations\n\n1. **Avoid using `origin: '*'` with `credentials: true`**: This is not allowed by the CORS specification\n2. **Validate origins carefully**: Use specific origins or a whitelist instead of wildcards in production\n3. **Limit exposed headers**: Only expose headers that are necessary for your application\n4. **Set appropriate maxAge**: Balance between performance and security\n\n## TypeScript Support\n\nThis package includes full TypeScript type definitions:\n\n```typescript\nimport cors, { CorsOptions, CorsOptionsDelegate } from '@amitpatel-wstf/cors';\n\nconst options: CorsOptions = {\n  origin: 'http://example.com',\n  credentials: true\n};\n\napp.use(cors(options));\n```\n\n## Testing\n\nRun the test suite:\n\n```bash\nnpm test\n```\n\nRun tests with Node.js test runner:\n\n```bash\nnode --test tests/cors.test.ts\n```\n\n## Building\n\nBuild the TypeScript source:\n\n```bash\nnpm run build\n```\n\nWatch mode for development:\n\n```bash\nnpm run dev\n```\n\n## Browser Support\n\nThis middleware works with all modern browsers that support CORS:\n- Chrome\n- Firefox\n- Safari\n- Edge\n- Opera\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Author\n\nAmit Patel\n\n## Repository\n\nhttps://github.com/amitpatel-wstf/cors\n\n## Related\n\n- [Express](https://expressjs.com/)\n- [CORS Specification](https://www.w3.org/TR/cors/)\n- [MDN CORS Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)\n","readmeFilename":"README.md"}