{"id":18317911,"url":"https://github.com/idiocc/cors","last_synced_at":"2025-08-03T18:33:30.569Z","repository":{"id":57113702,"uuid":"226712961","full_name":"idiocc/cors","owner":"idiocc","description":"Cross-Origin Resource Sharing (CORS) For Goa.","archived":false,"fork":false,"pushed_at":"2020-01-09T14:44:53.000Z","size":110,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-11T21:06:29.496Z","etag":null,"topics":["cors","goa","idio"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/idiocc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-08T18:33:14.000Z","updated_at":"2020-01-09T14:44:56.000Z","dependencies_parsed_at":"2022-08-22T05:31:09.243Z","dependency_job_id":null,"html_url":"https://github.com/idiocc/cors","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":"mnpjs/package","purl":"pkg:github/idiocc/cors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fcors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fcors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fcors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fcors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/idiocc","download_url":"https://codeload.github.com/idiocc/cors/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fcors/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268594450,"owners_count":24275737,"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","status":"online","status_checked_at":"2025-08-03T02:00:12.545Z","response_time":2577,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","goa","idio"],"created_at":"2024-11-05T18:07:50.490Z","updated_at":"2025-08-03T18:33:30.531Z","avatar_url":"https://github.com/idiocc.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @goa/cors\n\n[![npm version](https://badge.fury.io/js/%40goa%2Fcors.svg)](https://www.npmjs.com/package/@goa/cors)\n\n`@goa/cors` is Cross-Origin Resource Sharing ([CORS](https://developer.mozilla.org/en/docs/Web/HTTP/Access_control_CORS)) For Goa.\n\n```sh\nyarn add @goa/cors\n```\n\n## Table Of Contents\n\n- [Table Of Contents](#table-of-contents)\n- [API](#api)\n- [`cors(config=: !CorsConfig): !Middleware`](#corsconfig-corsconfig-middleware)\n  * [`CorsConfig`](#type-corsconfig)\n- [Usage Events](#usage-events)\n- [Copyright \u0026 License](#copyright--license)\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/0.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n\n## API\n\nThe package is available by importing its default function:\n\n```js\nimport cors from '@goa/cors'\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## \u003ccode\u003e\u003cins\u003ecors\u003c/ins\u003e(\u003c/code\u003e\u003csub\u003e\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`config=: !CorsConfig,`\u003cbr/\u003e\u003c/sub\u003e\u003ccode\u003e): \u003ci\u003e!Middleware\u003c/i\u003e\u003c/code\u003e\nCross-Origin Resource Sharing (CORS) For Goa.\n\n - \u003ckbd\u003econfig\u003c/kbd\u003e \u003cem\u003e\u003ccode\u003e\u003ca href=\"#type-corsconfig\" title=\"Options for the program.\"\u003e!CorsConfig\u003c/a\u003e\u003c/code\u003e\u003c/em\u003e (optional): The config.\n\n__\u003ca name=\"type-corsconfig\"\u003e`CorsConfig`\u003c/a\u003e__: Options for the program.\n\u003ctable\u003e\n \u003cthead\u003e\u003ctr\u003e\n  \u003cth\u003eName\u003c/th\u003e\n  \u003cth\u003eType \u0026amp; Description\u003c/th\u003e\n  \u003cth\u003eDefault\u003c/th\u003e\n \u003c/tr\u003e\u003c/thead\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003eorigin\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e(string | function(\u003ca href=\"https://github.com/idiocc/goa/wiki/Context#type-context\" title=\"The context object for each request.\"\u003e!Context\u003c/a\u003e))\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e-\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   \u003ccode\u003eAccess-Control-Allow-Origin\u003c/code\u003e header, default is taken from the \u003ccode\u003eOrigin\u003c/code\u003e request header.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003eallowMethods\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e(string | !Array\u0026lt;string\u0026gt;)\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e\u003ccode\u003eGET,HEAD,PUT,POST,DELETE,PATCH\u003c/code\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   \u003ccode\u003eAccess-Control-Allow-Methods\u003c/code\u003e header.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003eexposeHeaders\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e(string | !Array\u0026lt;string\u0026gt;)\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e-\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   \u003ccode\u003eAccess-Control-Expose-Headers\u003c/code\u003e header.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003eallowHeaders\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e(string | !Array\u0026lt;string\u0026gt;)\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e-\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   \u003ccode\u003eAccess-Control-Allow-Headers\u003c/code\u003e header.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003emaxAge\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003e(string | number)\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e-\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   \u003ccode\u003eAccess-Control-Max-Age\u003c/code\u003e header in seconds.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003ecredentials\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003eboolean\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   \u003ccode\u003eAccess-Control-Max-Age\u003c/code\u003e header in seconds.\n  \u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd rowSpan=\"3\" align=\"center\"\u003ekeepHeadersOnError\u003c/td\u003e\n  \u003ctd\u003e\u003cem\u003eboolean\u003c/em\u003e\u003c/td\u003e\n  \u003ctd rowSpan=\"3\"\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\n \u003c/tr\u003e\n \u003ctr\u003e\u003c/tr\u003e\n \u003ctr\u003e\n  \u003ctd\u003e\n   Add set headers to \u003ccode\u003eerr.header\u003c/code\u003e if an error is thrown.\n  \u003c/td\u003e\n \u003c/tr\u003e\n\u003c/table\u003e\n\nThere are 3 main use cases:\n\n**1. Accept any origin form the client**\n\n```js\nimport Goa from '@goa/koa'\nimport { aqt } from 'rqt'\nimport cors from '@goa/cors'\n\nconst goa = new Goa()\ngoa.use(cors())\n\ngoa.listen(async function() {\n  const { port } = this.address()\n  const url = `http://localhost:${port}`\n\n  // 1. accept origin from the host\n  const { headers } = await aqt(url, {\n    headers: {\n      origin: 'www.example.com',\n    },\n  })\n  console.log(headers)\n  this.close()\n})\n```\n```js\n{ vary: 'Origin',\n  'access-control-allow-origin': 'www.example.com',\n  'content-type': 'text/plain; charset=utf-8',\n  'content-length': '9',\n  date: 'Thu, 09 Jan 2020 14:43:05 GMT',\n  connection: 'close' }\n```\n\n**2. Send out only specific origin**\n\n```js\nimport Goa from '@goa/koa'\nimport { aqt } from 'rqt'\nimport cors from '@goa/cors'\n\nconst goa = new Goa()\ngoa.use(cors({\n  origin: 'www.hello-world.com',\n}))\n\ngoa.listen(async function() {\n  const { port } = this.address()\n  const url = `http://localhost:${port}`\n\n  // 2. only serve specific origin\n  const { headers } = await aqt(url, {\n    headers: {\n      origin: 'www.example.com',\n    },\n  })\n  console.log(headers)\n  this.close()\n})\n```\n```js\n{ vary: 'Origin',\n  'access-control-allow-origin': 'www.hello-world.com',\n  'content-type': 'text/plain; charset=utf-8',\n  'content-length': '9',\n  date: 'Thu, 09 Jan 2020 14:43:05 GMT',\n  connection: 'close' }\n```\n\n**3. Pre-flight Requests Via OPTIONS (both above apply)**\n\n```js\nimport Goa from '@goa/koa'\nimport { aqt } from 'rqt'\nimport cors from '@goa/cors'\n\nconst goa = new Goa()\ngoa.use(cors({\n  origin: 'www.hello-world.com',\n  credentials: true,\n  maxAge: 1000,\n  allowMethods: ['POST', 'PUT'],\n}))\n\ngoa.listen(async function() {\n  const { port } = this.address()\n  const url = `http://localhost:${port}`\n\n  // 3. respond to pre-flight request\n  const { statusCode, headers } = await aqt(url, {\n    method: 'OPTIONS',\n    headers: {\n      'Access-Control-Request-Method': 'POST',\n      origin: 'www.example.com',\n    },\n  })\n  console.log(statusCode, headers)\n  this.close()\n})\n```\n```js\n204 { vary: 'Origin',\n  'access-control-allow-origin': 'www.hello-world.com',\n  'access-control-allow-credentials': 'true',\n  'access-control-max-age': '1000',\n  'access-control-allow-methods': 'POST,PUT',\n  date: 'Thu, 09 Jan 2020 14:43:05 GMT',\n  connection: 'close' }\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/2.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Usage Events\n\nThis middleware integrates with [_Idio_](https://github.com/idiocc/idio) that collects middleware usage statistics to reward package maintainers. It will emit certain events to bill its usage:\n\n1. `headers`: When setting the headers if origin was present.\n1. `options`: When responding to pre-flight requests via the `OPTIONS` http method.\n\nThe usage is recorded via the `ctx.neoluddite` context property set by a server such as _Idio_. In future, more fine-grained usage events might appear.\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/3.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Copyright \u0026 License\n\nGNU Affero General Public License v3.0\n\nAffero GPL means that you're not allowed to use this middleware on the web unless you release the source code for your application. This is a restrictive license which has the purpose of defending Open Source work and its creators.\n\nPlease refer to the [Idio license agreement](https://github.com/idiocc/idio#copyright--license) for more info on dual-licensing. You're allowed to use this middleware without disclosing the source code if you sign up on [neoluddite.dev](https://neoluddite.dev) package reward scheme.\n\nOriginal Work by [dead-horse \u0026 contributors](https://github.com/koajs/cors) licensed under MIT found in [COPYING](COPYING).\n\n\u003ctable\u003e\n  \u003ctr\u003e\u003ctd\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/40834161?s=100\" alt=\"idiocc\"\u003e\u003c/td\u003e\u003ctd\u003e© \u003ca href=\"https://www.idio.cc\"\u003eIdio\u003c/a\u003e 2020\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/-1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidiocc%2Fcors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidiocc%2Fcors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidiocc%2Fcors/lists"}