{"id":18011243,"url":"https://github.com/tajpouria/cors","last_synced_at":"2025-03-26T15:32:37.793Z","repository":{"id":45556145,"uuid":"264523976","full_name":"tajpouria/cors","owner":"tajpouria","description":"Deno.js CORS middleware.","archived":false,"fork":false,"pushed_at":"2024-06-07T17:01:34.000Z","size":93,"stargazers_count":73,"open_issues_count":3,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-19T21:47:37.645Z","etag":null,"topics":["cors","deno"],"latest_commit_sha":null,"homepage":"https://deno.land/x/cors@v1.2.2","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tajpouria.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-16T20:44:46.000Z","updated_at":"2025-01-10T01:15:40.000Z","dependencies_parsed_at":"2022-09-09T11:23:04.923Z","dependency_job_id":null,"html_url":"https://github.com/tajpouria/cors","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tajpouria%2Fcors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tajpouria%2Fcors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tajpouria%2Fcors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tajpouria%2Fcors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tajpouria","download_url":"https://codeload.github.com/tajpouria/cors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245681522,"owners_count":20655214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cors","deno"],"created_at":"2024-10-30T03:07:57.418Z","updated_at":"2025-03-26T15:32:37.467Z","avatar_url":"https://github.com/tajpouria.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cors\n\n[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/cors/mod.ts)\n[![nest badge](https://nest.land/badge.svg)](https://nest.land/package/cors)\n[![JSR](https://jsr.io/badges/@tajpouria/cors)](https://jsr.io/@tajpouria/cors)\n\nCORS is a Deno.js module for providing a\n[Oak](https://github.com/oakserver/oak)/[Opine](https://github.com/asos-craigmorten/opine)/[Abc](https://github.com/zhmushan/abc)/[Attain](https://github.com/aaronwlee/Attain)/[Mith](https://github.com/jwebcoder/mith)\nmiddleware that can be used to enable\n[CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) with various\noptions.\n\n- [Usage](#usage)\n  - [Simple Usage](#simple-usage-enable-all-cors-requests)\n  - [Enable CORS for a Single Route](#enable-cors-for-a-single-route)\n  - [Configuring CORS](#configuring-cors)\n  - [Configuring CORS w/ Dynamic Origin](#configuring-cors-w-dynamic-origin)\n  - [Enabling CORS Pre-Flight](#enabling-cors-pre-flight)\n  - [Configuring CORS Asynchronously](#configuring-cors-asynchronously)\n- [Configuration Options](#configuration-options)\n- [Examples](#examples)\n\n## Usage\n\n### Simple Usage (Enable All CORS Requests)\n\n```typescript\nimport { Application, Router, send } from \"https://deno.land/x/oak/mod.ts\";\nimport { oakCors } from \"https://deno.land/x/cors/mod.ts\";\n\nconst books = new Map\u003cstring, any\u003e();\nbooks.set(\"1\", {\n  id: \"1\",\n  title: \"Frankenstein\",\n  author: \"Mary Shelley\",\n});\n\nconst router = new Router();\nrouter\n  .get(\"/\", async (context) =\u003e {\n    await send(context, context.request.url.pathname, {\n      root: `${Deno.cwd()}/static`,\n      index: \"index.html\",\n    });\n  })\n  .get(\"/book\", (context) =\u003e {\n    context.response.body = Array.from(books.values());\n  })\n  .get(\"/book/:id\", (context) =\u003e {\n    if (context.params \u0026\u0026 context.params.id \u0026\u0026 books.has(context.params.id)) {\n      context.response.body = books.get(context.params.id);\n    }\n  });\n\nconst app = new Application();\napp.use(oakCors()); // Enable CORS for All Routes\napp.use(router.routes());\n\nconsole.info(\"CORS-enabled web server listening on port 8000\");\nawait app.listen({ port: 8000 });\n```\n\n### Enable CORS for a Single Route\n\n```typescript\nimport { Application, Router } from \"https://deno.land/x/oak/mod.ts\";\nimport { oakCors } from \"https://deno.land/x/cors/mod.ts\";\n\nconst books = new Map\u003cstring, any\u003e();\nbooks.set(\"1\", {\n  id: \"1\",\n  title: \"Frankenstein\",\n  author: \"Mary Shelley\",\n});\n\nconst router = new Router();\nrouter\n  .get(\"/book\", (context) =\u003e {\n    context.response.body = Array.from(books.values());\n  })\n  // Enable CORS for a Single Route\n  .get(\"/book/:id\", oakCors(), (context) =\u003e {\n    if (context.params.id \u0026\u0026 books.has(context.params.id)) {\n      context.response.body = books.get(context.params.id);\n    }\n  });\n\nconst app = new Application();\napp.use(router.routes());\n\nconsole.info(\"CORS-enabled web server listening on port 8000\");\nawait app.listen({ port: 8000 });\n```\n\n### Configuring CORS\n\n```typescript\nimport { Application, Router } from \"https://deno.land/x/oak/mod.ts\";\nimport { oakCors } from \"https://deno.land/x/cors/mod.ts\";\n\nconst books = new Map\u003cstring, any\u003e();\nbooks.set(\"1\", {\n  id: \"1\",\n  title: \"Frankenstein\",\n  author: \"Mary Shelley\",\n});\n\nconst router = new Router();\nrouter.get(\"/book\", (context) =\u003e {\n  context.response.body = Array.from(books.values());\n});\n\nconst app = new Application();\napp.use(\n  oakCors({\n    origin: /^.+localhost:(1234|3000)$/,\n    optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204\n  })\n);\napp.use(router.routes());\n\nconsole.info(\"CORS-enabled web server listening on port 8000\");\nawait app.listen({ port: 8000 });\n```\n\n### Configuring CORS w/ Dynamic Origin\n\nThis module supports validating the origin dynamically using a function provided\nto the `origin` option. This function will be passed a string that is the origin\n(or `undefined` if the request has no origin), and a `callback` with the\nsignature `callback(error, origin)`.\n\nThe `origin` argument to the callback can be any value allowed for the `origin`\noption of the middleware, except a function. See the\n[configuration options](#configuration-options) section for more information on\nall the possible value types.\n\nThis function is designed to allow the dynamic loading of allowed origin(s) from\na backing dataSource, like a database.\n\n```typescript\nimport { Application, Router } from \"https://deno.land/x/oak/mod.ts\";\nimport { oakCors } from \"https://deno.land/x/cors/mod.ts\";\n\nconst sleep = (ms: number) =\u003e\n  new Promise((resolve) =\u003e {\n    setTimeout(resolve, ms);\n  });\n\nconst loadOriginsFromDataBase = async () =\u003e {\n  await sleep(3000);\n  return [\"http://localhost:1234\", \"http://localhost:3000\"];\n};\n\nconst books = new Map\u003cstring, any\u003e();\nbooks.set(\"1\", {\n  id: \"1\",\n  title: \"Frankenstein\",\n  author: \"Mary Shelley\",\n});\n\nconst corsOptions: CorsOptions = {\n  origin: async (requestOrigin) =\u003e {\n    const origins = await loadOriginsFromDataBase(); // Simulate asynchronous task\n\n    return origins; //  Reflect (enable) the requested origin in the CORS response for this origins\n  },\n};\n\nconst router = new Router();\nrouter.get(\"/book\", oakCors(corsOptions), (context) =\u003e {\n  context.response.body = Array.from(books.values());\n});\n\nconst app = new Application();\napp.use(router.routes());\n\nconsole.info(\"CORS-enabled web server listening on port 8000\");\nawait app.listen({ port: 8000 });\n```\n\nIf you do not want to block REST tools or server-to-server requests, add a\n!requestOrigin check in the origin function like so:\n\n```typescript\nconst corsOptions = {\n  origin: (requestOrigin) =\u003e {\n    if (!requestOrigin) {\n      return true;\n    } else {\n      thrown new Error(\"Not allowed by CORS\");\n    }\n  },\n};\n```\n\n### Enabling CORS Pre-Flight\n\nCertain CORS requests are considered 'complex' and require an initial `OPTIONS`\nrequest (called the \"pre-flight request\"). An example of a 'complex' CORS\nrequest is one that uses an HTTP verb other than GET/HEAD/POST (such as DELETE)\nor that uses custom headers. To enable pre-flighting, you must add a new OPTIONS\nhandler for the route you want to support:\n\n```typescript\nimport { Application, Router } from \"https://deno.land/x/oak/mod.ts\";\nimport { oakCors } from \"https://deno.land/x/cors/mod.ts\";\n\nconst books = new Map\u003cstring, any\u003e();\nbooks.set(\"1\", {\n  id: \"1\",\n  title: \"Frankenstein\",\n  author: \"Mary Shelley\",\n});\n\nconst router = new Router();\nrouter\n  .options(\"/book/:id\", oakCors()) // enable pre-flight request for OPTIONS request\n  .delete(\"/book/:id\", oakCors(), (context) =\u003e {\n    if (context.params \u0026\u0026 context.params.id \u0026\u0026 books.has(context.params.id)) {\n      books.delete(context.params.id);\n      context.response.body = { ok: true };\n    }\n  });\n\nconst app = new Application();\napp.use(router.routes());\n\nconsole.info(\"CORS-enabled web server listening on port 8000\");\nawait app.listen({ port: 8000 });\n```\n\nNOTE: When using this middleware as an application level middleware (for\nexample, `app.use(oakCors())`), pre-flight requests are already handled for all\nroutes.\n\n### Configuring CORS Asynchronously\n\n```typescript\nimport { Application, Router } from \"https://deno.land/x/oak/mod.ts\";\nimport { oakCors } from \"https://deno.land/x/cors/mod.ts\";\n\nconst sleep = (ms: number) =\u003e\n  new Promise((resolve) =\u003e {\n    setTimeout(resolve, ms);\n  });\n\nconst books = new Map\u003cstring, any\u003e();\nbooks.set(\"1\", {\n  id: \"1\",\n  title: \"Frankenstein\",\n  author: \"Mary Shelley\",\n});\n\nconst whitelist = [\"http://localhost:1234\", \"http://localhost:3000\"];\n\nconst corsOptionsDelegate: CorsOptionsDelegate\u003cRequest\u003e = async (request) =\u003e {\n  const isOriginAllowed = whitelist.includes(\n    request.headers.get(\"origin\") ?? \"\"\n  );\n\n  await sleep(3000); // Simulate asynchronous task\n\n  return { origin: isOriginAllowed }; //  Reflect (enable) the requested origin in the CORS response if isOriginAllowed is true\n};\n\nconst router = new Router();\nrouter.get(\"/book/:id\", oakCors(corsOptionsDelegate), (context) =\u003e {\n  context.response.body = Array.from(books.values());\n});\n\nconst app = new Application();\napp.use(router.routes());\n\nconsole.info(\"CORS-enabled web server listening on port 8000\");\nawait app.listen({ port: 8000 });\n```\n\n## Configuration Options\n\n- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible\n  values:\n  - `Boolean` - set `origin` to `true` to reflect the\n    [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as\n    defined by `req.header('Origin')`, or set it to `false` to disable CORS.\n  - `String` - set `origin` to a specific origin. For example if you set it to\n    `\"http://example.com\"` only requests from \"http://example.com\" will be\n    allowed.\n  - `RegExp` - set `origin` to a regular expression pattern which will be used\n    to test the request origin. If it's a match, the request origin will be\n    reflected. For example the pattern `/example\\.com$/` will reflect any\n    request that is coming from an origin ending with \"example.com\".\n  - `Array` - set `origin` to an array of valid origins. Each origin can be a\n    `String` or a `RegExp`. For example\n    `[\"http://example1.com\", /\\.example2\\.com$/]` will accept any request from\n    \"http://example1.com\" or from a subdomain of \"example2.com\".\n  - `Function` - set `origin` to a function implementing some custom logic. The\n    function takes the request origin as the first parameter and a callback\n    (called as `callback(err, origin)`, where `origin` is a non-function value\n    of the `origin` option) as the second.\n- `methods`: Configures the **Access-Control-Allow-Methods** CORS header.\n  Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex:\n  `['GET', 'PUT', 'POST']`).\n- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header.\n  Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an\n  array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to\n  reflecting the headers specified in the request's\n  **Access-Control-Request-Headers** header.\n- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS\n  header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range')\n  or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no\n  custom headers are exposed.\n- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS\n  header. Set to `true` to pass the header, otherwise it is omitted.\n- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an\n  integer to pass the header, otherwise it is omitted.\n- `preflightContinue`: Pass the CORS preflight response to the next handler.\n- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS`\n  requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.\n\nThe default configuration is the equivalent of:\n\n```json\n{\n  \"origin\": \"*\",\n  \"methods\": \"GET,HEAD,PUT,PATCH,POST,DELETE\",\n  \"preflightContinue\": false,\n  \"optionsSuccessStatus\": 204\n}\n```\n\n## Examples\n\nDocument example can be found here:\n\n- [Oak](./examples/oak)\n- [Opine](./examples/opine)\n- [Abc](./examples/abc)\n- [Attain](./examples/attain)\n- [Mith](./examples/mith)\n\n## License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftajpouria%2Fcors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftajpouria%2Fcors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftajpouria%2Fcors/lists"}