[
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n"
  },
  {
    "path": ".github/workflows/nodejs.yml",
    "content": "name: Node.js CI\n\non: [push]\n\npermissions:\n  contents: read\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [18.x, 20.x, 22.x, 24.x]\n\n    steps:\n      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          persist-credentials: false\n      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0\n        with:\n          node-version: ${{ matrix.node-version }}\n          check-latest: true\n      - run: npm ci\n      - run: npm test\n        env:\n          CI: true\n"
  },
  {
    "path": ".gitignore",
    "content": "/node_modules/\n/coverage/\n.eslintcache\n"
  },
  {
    "path": ".prettierignore",
    "content": "/coverage/\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n- `Cross-Origin-Opener-Policy`: support `noopener-allow-popups`. See [#522](https://github.com/helmetjs/helmet/pull/522)\n- Improve error message when passing duplicate options\n\n## 8.1.0 - 2025-03-17\n\n### Changed\n\n- `Content-Security-Policy` gives a better error when a directive value, like `self`, should be quoted. See [#482](https://github.com/helmetjs/helmet/issues/482)\n\n## 8.0.0 - 2024-09-28\n\n### Changed\n\n- **Breaking:** `Strict-Transport-Security` now has a max-age of 365 days, up from 180\n- **Breaking:** `Content-Security-Policy` middleware now throws an error if a directive should have quotes but does not, such as `self` instead of `'self'`. See [#454](https://github.com/helmetjs/helmet/issues/454)\n- **Breaking:** `Content-Security-Policy`'s `getDefaultDirectives` now returns a deep copy. This only affects users who were mutating the result\n- **Breaking:** `Strict-Transport-Security` now throws an error when \"includeSubDomains\" option is misspelled. This was previously a warning\n\n### Removed\n\n- **Breaking:** Drop support for Node 16 and 17. Node 18+ is now required\n\n## 7.2.0 - 2024-09-28\n\n### Changed\n\n- `Content-Security-Policy` middleware now warns if a directive should have quotes but does not, such as `self` instead of `'self'`. This will be an error in future versions. See [#454](https://github.com/helmetjs/helmet/issues/454)\n\n## 7.1.0 - 2023-11-07\n\n### Added\n\n- `helmet.crossOriginEmbedderPolicy` now supports the `unsafe-none` directive. See [#447](https://github.com/helmetjs/helmet/pull/447)\n\n## 7.0.0 - 2023-05-06\n\n### Changed\n\n- **Breaking:** `Cross-Origin-Embedder-Policy` middleware is now disabled by default. See [#411](https://github.com/helmetjs/helmet/issues/411)\n\n### Removed\n\n- **Breaking:** Drop support for Node 14 and 15. Node 16+ is now required\n- **Breaking:** `Expect-CT` is no longer part of Helmet. If you still need it, you can use the [`expect-ct` package](https://www.npmjs.com/package/expect-ct). See [#378](https://github.com/helmetjs/helmet/issues/378)\n\n## 6.2.0 - 2023-05-06\n\n- Expose header names (e.g., `strictTransportSecurity` for the `Strict-Transport-Security` header, instead of `hsts`)\n- Rework documentation\n\n## 6.1.5 - 2023-04-11\n\n### Fixed\n\n- Fixed yet another issue with TypeScript exports. See [#420](https://github.com/helmetjs/helmet/pull/420)\n\n## 6.1.4 - 2023-04-10\n\n### Fixed\n\n- Fix another issue with TypeScript default exports. See [#418](https://github.com/helmetjs/helmet/pull/418)\n\n## 6.1.3 - 2023-04-10\n\n### Fixed\n\n- Fix issue with TypeScript default exports. See [#417](https://github.com/helmetjs/helmet/pull/417)\n\n## 6.1.2 - 2023-04-09\n\n### Fixed\n\n- Retored `main` to package to help with some build tools\n\n## 6.1.1 - 2023-04-08\n\n### Fixed\n\n- Fixed missing package metadata\n\n## 6.1.0 - 2023-04-08\n\n### Changed\n\n- Improve support for various TypeScript setups, including \"nodenext\". See [#405](https://github.com/helmetjs/helmet/pull/405)\n\n## 6.0.1 - 2022-11-29\n\n### Fixed\n\n- `crossOriginEmbedderPolicy` did not accept options at the top level. See [#390](https://github.com/helmetjs/helmet/issues/390)\n\n## 6.0.0 - 2022-08-26\n\n### Changed\n\n- **Breaking:** `helmet.contentSecurityPolicy` no longer sets `block-all-mixed-content` directive by default\n- **Breaking:** `helmet.expectCt` is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. See [#310](https://github.com/helmetjs/helmet/issues/310)\n- **Breaking:** Increase TypeScript strictness around some arguments. Only affects TypeScript users, and may not require any code changes. See [#369](https://github.com/helmetjs/helmet/issues/369)\n- `helmet.frameguard` no longer offers a specific error when trying to use `ALLOW-FROM`; it just says that it is unsupported. Only the error message has changed\n\n### Removed\n\n- **Breaking:** Dropped support for Node 12 and 13. Node 14+ is now required\n\n## 5.1.1 - 2022-07-23\n\n### Changed\n\n- Fix TypeScript bug with some TypeScript configurations. See [#375](https://github.com/helmetjs/helmet/pull/375) and [#359](https://github.com/helmetjs/helmet/issues/359)\n\n## 5.1.0 - 2022-05-17\n\n### Added\n\n- `Cross-Origin-Embedder-Policy`: support `credentialless` policy. See [#365](https://github.com/helmetjs/helmet/pull/365)\n- Documented how to set both `Content-Security-Policy` and `Content-Security-Policy-Report-Only`\n\n### Changed\n\n- Cleaned up some documentation around `Origin-Agent-Cluster`\n\n## 5.0.2 - 2022-01-22\n\n### Changed\n\n- Improve imports for CommonJS and ECMAScript modules. See [#345](https://github.com/helmetjs/helmet/pull/345)\n- Fixed some documentation\n\n## 5.0.1 - 2022-01-03\n\n### Changed\n\n- Fixed some documentation\n\n### Removed\n\n- Removed some unused internal code\n\n## 5.0.0 - 2022-01-02\n\n### Added\n\n- ECMAScript module imports (i.e., `import helmet from \"helmet\"` and `import { frameguard } from \"helmet\"`). See [#320](https://github.com/helmetjs/helmet/issues/320)\n\n### Changed\n\n- **Breaking:** `helmet.contentSecurityPolicy`: `useDefaults` option now defaults to `true`\n- **Breaking:** `helmet.contentSecurityPolicy`: `form-action` directive is now set to `'self'` by default\n- **Breaking:** `helmet.crossOriginEmbedderPolicy` is enabled by default\n- **Breaking:** `helmet.crossOriginOpenerPolicy` is enabled by default\n- **Breaking:** `helmet.crossOriginResourcePolicy` is enabled by default\n- **Breaking:** `helmet.originAgentCluster` is enabled by default\n- `helmet.frameguard`: add TypeScript editor autocomplete. See [#322](https://github.com/helmetjs/helmet/pull/322)\n- Top-level `helmet()` function is slightly faster\n\n### Removed\n\n- **Breaking:** Drop support for Node 10 and 11. Node 12+ is now required\n\n## 4.6.0 - 2021-05-01\n\n### Added\n\n- `helmet.contentSecurityPolicy`: the `useDefaults` option, defaulting to `false`, lets you selectively override defaults more easily\n- Explicitly define TypeScript types in `package.json`. See [#303](https://github.com/helmetjs/helmet/pull/303)\n\n## 4.5.0 - 2021-04-17\n\n### Added\n\n- `helmet.crossOriginEmbedderPolicy`: a new middleware for the `Cross-Origin-Embedder-Policy` header, disabled by default\n- `helmet.crossOriginOpenerPolicy`: a new middleware for the `Cross-Origin-Opener-Policy` header, disabled by default\n- `helmet.crossOriginResourcePolicy`: a new middleware for the `Cross-Origin-Resource-Policy` header, disabled by default\n\n### Changed\n\n- `true` enables a middleware with default options. Previously, this would fail with an error if the middleware was already enabled by default.\n- Log a warning when passing options to `originAgentCluster` at the top level\n\n### Fixed\n\n- Incorrect documentation\n\n## 4.4.1 - 2021-01-18\n\n### Changed\n\n- Shrink the published package by about 2.5 kB\n\n## 4.4.0 - 2021-01-17\n\n### Added\n\n- `helmet.originAgentCluster`: a new middleware for the `Origin-Agent-Cluster` header, disabled by default\n\n## 4.3.1 - 2020-12-27\n\n### Fixed\n\n- `helmet.contentSecurityPolicy`: broken TypeScript types. See [#283](https://github.com/helmetjs/helmet/issues/283)\n\n## 4.3.0 - 2020-12-27\n\n### Added\n\n- `helmet.contentSecurityPolicy`: setting the `default-src` to `helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc` disables it\n\n### Changed\n\n- `helmet.frameguard`: slightly improved error messages for non-strings\n\n## 4.2.0 - 2020-11-01\n\n### Added\n\n- `helmet.contentSecurityPolicy`: get the default directives with `contentSecurityPolicy.getDefaultDirectives()`\n\n### Changed\n\n- `helmet()` now supports objects that don't have `Object.prototype` in their chain, such as `Object.create(null)`, as options\n- `helmet.expectCt`: `max-age` is now first. See [#264](https://github.com/helmetjs/helmet/pull/264)\n\n## 4.1.1 - 2020-09-10\n\n### Changed\n\n- Fixed a few errors in the README\n\n## 4.1.0 - 2020-08-15\n\n### Added\n\n- `helmet.contentSecurityPolicy`:\n  - Directive values can now include functions, as they could in Helmet 3. See [#243](https://github.com/helmetjs/helmet/issues/243)\n\n### Changed\n\n- Helmet should now play more nicely with TypeScript\n\n### Removed\n\n- The `HelmetOptions` interface is no longer exported. This only affects TypeScript users. If you need the functionality back, see [this comment](https://github.com/helmetjs/helmet/issues/235#issuecomment-674016883)\n\n## 4.0.0 - 2020-08-02\n\nSee the [Helmet 4 upgrade guide](https://github.com/helmetjs/helmet/wiki/Helmet-4-upgrade-guide) for help upgrading from Helmet 3.\n\n### Added\n\n- `helmet.contentSecurityPolicy`:\n  - If no `default-src` directive is supplied, an error is thrown\n  - Directive lists can be any iterable, not just arrays\n\n### Changed\n\n- This package no longer has dependencies. This should have no effect on end users, other than speeding up installation time.\n- `helmet.contentSecurityPolicy`:\n  - There is now a default set of directives if none are supplied\n  - Duplicate keys now throw an error. See [helmetjs/csp#73](https://github.com/helmetjs/csp/issues/73)\n  - This middleware is more lenient, allowing more directive names or values\n- `helmet.xssFilter` now disables the buggy XSS filter by default. See [#230](https://github.com/helmetjs/helmet/issues/230)\n\n### Removed\n\n- Dropped support for old Node versions. Node 10+ is now required\n- `helmet.featurePolicy`. If you still need it, use the `feature-policy` package on npm.\n- `helmet.hpkp`. If you still need it, use the `hpkp` package on npm.\n- `helmet.noCache`. If you still need it, use the `nocache` package on npm.\n- `helmet.contentSecurityPolicy`:\n  - Removed browser sniffing (including the `browserSniff` and `disableAndroid` parameters). See [helmetjs/csp#97](https://github.com/helmetjs/csp/issues/97)\n  - Removed conditional support. This includes directive functions and support for a function as the `reportOnly`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware)\n  - Removed a lot of checks—you should be checking your CSP with a different tool\n  - Removed support for legacy headers (and therefore the `setAllHeaders` parameter). [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Setting-legacy-Content-Security-Policy-headers-in-Helmet-4)\n  - Removed the `loose` option\n  - Removed support for functions as directive values. You must supply an iterable of strings\n- `helmet.frameguard`:\n  - Dropped support for the `ALLOW-FROM` action. [Read more here.](https://github.com/helmetjs/helmet/wiki/How-to-use-X%E2%80%93Frame%E2%80%93Options's-%60ALLOW%E2%80%93FROM%60-directive)\n- `helmet.hidePoweredBy` no longer accepts arguments. See [this article](https://github.com/helmetjs/helmet/wiki/How-to-set-a-custom-X%E2%80%93Powered%E2%80%93By-header) to see how to replicate the removed behavior. See [#224](https://github.com/helmetjs/helmet/issues/224).\n- `helmet.hsts`:\n  - Dropped support for `includeSubdomains` with a lowercase D. See [#231](https://github.com/helmetjs/helmet/issues/231)\n  - Dropped support for `setIf`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware) See [#232](https://github.com/helmetjs/helmet/issues/232)\n- `helmet.xssFilter` no longer accepts options. Read [\"How to disable blocking with X-XSS-Protection\"](https://github.com/helmetjs/helmet/wiki/How-to-disable-blocking-with-X%E2%80%93XSS%E2%80%93Protection) and [\"How to enable the `report` directive with X-XSS-Protection\"](https://github.com/helmetjs/helmet/wiki/How-to-enable-the-%60report%60-directive-with-X%E2%80%93XSS%E2%80%93Protection) if you need the legacy behavior.\n\n## 3.23.3 - 2020-06-26\n\n### Changed\n\n- `helmet.expectCt` is no longer a separate package. This should have no effect on end users.\n- `helmet.frameguard` is no longer a separate package. This should have no effect on end users.\n\n## 3.23.2 - 2020-06-23\n\n### Changed\n\n- `helmet.dnsPrefetchControl` is no longer a separate package. This should have no effect on end users.\n\n## 3.23.1 - 2020-06-16\n\n### Changed\n\n- `helmet.ieNoOpen` is no longer a separate package. This should have no effect on end users.\n\n## 3.23.0 - 2020-06-12\n\n### Deprecated\n\n- `helmet.featurePolicy` is deprecated. Use the `feature-policy` module instead.\n\n## 3.22.1 - 2020-06-10\n\n### Changed\n\n- Rewrote internals in TypeScript. This should have no effect on end users.\n\n## 3.22.0 - 2020-03-24\n\n### Changed\n\n- Updated `helmet-csp` to v2.10.0\n  - Add support for the `allow-downloads` sandbox directive. See [helmet-csp#103](https://github.com/helmetjs/csp/pull/103)\n\n### Deprecated\n\n- `helmet.noCache` is deprecated. Use the `nocache` module instead. See [#215](https://github.com/helmetjs/helmet/issues/215)\n\n## 3.21.3 - 2020-02-24\n\n### Changed\n\n- Updated `helmet-csp` to v2.9.5\n  - Updated `bowser` subdependency from 2.7.0 to 2.9.0\n  - Fixed an issue some people were having when importing the `bowser` subdependency. See [helmet-csp#96](https://github.com/helmetjs/csp/issues/96) and [#101](https://github.com/helmetjs/csp/pull/101)\n\n## 3.21.2 - 2019-10-21\n\n### Changed\n\n- Updated `helmet-csp` to v2.9.4\n  - Updated `bowser` subdependency from 2.6.1 to 2.7.0. See [helmet-csp#94](https://github.com/helmetjs/csp/pull/94)\n\n## 3.21.1 - 2019-09-20\n\n### Fixed\n\n- Updated `helmet-csp` to v2.9.2\n  - Fixed a bug where a request from Firefox 4 could delete `default-src` from future responses\n  - Fixed tablet PC detection by updating `bowser` subdependency to latest version\n\n## 3.21.0 - 2019-09-04\n\n### Added\n\n- Updated `x-xss-protection` to v1.3.0\n  - Added `mode: null` to disable `mode=block`\n\n### Changed\n\n- Updated `helmet-csp` to v2.9.1\n  - Updated `bowser` subdependency from 2.5.3 to 2.5.4. See [helmet-csp#88](https://github.com/helmetjs/csp/pull/88)\n\n## 3.20.1 - 2019-08-28\n\n### Changed\n\n- Updated `helmet-csp` to v2.9.0\n\n## 3.20.0 - 2019-07-24\n\n### Changed\n\n- Updated `helmet-csp` to v2.8.0\n\n## 3.19.0 - 2019-07-17\n\n### Changed\n\n- Updated `dns-prefetch-control` to v0.2.0\n- Updated `dont-sniff-mimetype` to v1.1.0\n- Updated `helmet-crossdomain` to v0.4.0\n- Updated `hide-powered-by` to v1.1.0\n- Updated `x-xss-protection` to v1.2.0\n\n## 3.18.0 - 2019-05-05\n\n### Added\n\n- `featurePolicy` has 19 new features: `ambientLightSensor`, `documentDomain`, `documentWrite`, `encryptedMedia`, `fontDisplayLateSwap`, `layoutAnimations`, `legacyImageFormats`, `loadingFrameDefaultEager`, `oversizedImages`, `pictureInPicture`, `serial`, `syncScript`, `unoptimizedImages`, `unoptimizedLosslessImages`, `unoptimizedLossyImages`, `unsizedMedia`, `verticalScroll`, `wakeLock`, and `xr`\n\n### Changed\n\n- Updated `expect-ct` to v0.2.0\n- Updated `feature-policy` to v0.3.0\n- Updated `frameguard` to v3.1.0\n- Updated `nocache` to v2.1.0\n\n## 3.17.0 - 2019-05-03\n\n### Added\n\n- `referrerPolicy` now supports multiple values\n\n### Changed\n\n- Updated `referrerPolicy` to v1.2.0\n\n## 3.16.0 - 2019-03-10\n\n### Added\n\n- Add email to `bugs` field in `package.json`\n\n### Changed\n\n- Updated `hsts` to v2.2.0\n- Updated `ienoopen` to v1.1.0\n- Changelog is now in the [Keep A Changelog](https://keepachangelog.com/) format\n- Dropped support for Node <4. See [the commit](https://github.com/helmetjs/helmet/commit/a49cec3ca58cce484d2d05e1f908549caa92ed03) for more information\n- Updated Adam Baldwin's contact information\n\n### Deprecated\n\n- `helmet.hsts`'s `setIf` option has been deprecated and will be removed in `hsts@3`. See [helmetjs/hsts#22](https://github.com/helmetjs/hsts/issues/22) for more\n\n* The `includeSubdomains` option (with a lowercase `d`) has been deprecated and will be removed in `hsts@3`. Use the uppercase-D `includeSubDomains` option instead. See [helmetjs/hsts#21](https://github.com/helmetjs/hsts/issues/21) for more\n\n## 3.15.1 - 2019-02-10\n\n### Deprecated\n\n- The `hpkp` middleware has been deprecated. If you still need to use this module, install the standalone `hpkp` module from npm. See [#180](https://github.com/helmetjs/helmet/issues/180) for more.\n\n## 3.15.0 - 2018-11-07\n\n### Added\n\n- `helmet.featurePolicy` now supports four new features\n\n## 3.14.0 - 2018-10-09\n\n### Added\n\n- `helmet.featurePolicy` middleware\n\n## 3.13.0 - 2018-07-22\n\n### Added\n\n- `helmet.permittedCrossDomainPolicies` middleware\n\n## 3.12.2 - 2018-07-20\n\n### Fixed\n\n- Removed `lodash.reduce` dependency from `csp`\n\n## 3.12.1 - 2018-05-16\n\n### Fixed\n\n- `expectCt` should use comma instead of semicolon as delimiter\n\n## 3.12.0 - 2018-03-02\n\n### Added\n\n- `xssFilter` now supports `reportUri` option\n\n## 3.11.0 - 2018-02-09\n\n### Added\n\n- Main Helmet middleware is now named to help with debugging\n\n## 3.10.0 - 2018-01-23\n\n### Added\n\n- `csp` now supports `prefix-src` directive\n\n### Fixed\n\n- `csp` no longer loads JSON files internally, helping some module bundlers\n- `false` should be able to disable a CSP directive\n\n## 3.9.0 - 2017-10-13\n\n### Added\n\n- `csp` now supports `strict-dynamic` value\n- `csp` now supports `require-sri-for` directive\n\n### Changed\n\n- Removed `connect` dependency\n\n## 3.8.2 - 2017-09-27\n\n### Changed\n\n- Updated `connect` dependency to latest\n\n## 3.8.1 - 2017-07-28\n\n### Fixed\n\n- `csp` does not automatically set `report-to` when setting `report-uri`\n\n## 3.8.0 - 2017-07-21\n\n### Changed\n\n- `hsts` no longer cares whether it's HTTPS and always sets the header\n\n## 3.7.0 - 2017-07-21\n\n### Added\n\n- `csp` now supports `report-to` directive\n\n### Changed\n\n- Throw an error when used incorrectly\n- Add a few documentation files to `npmignore`\n\n## 3.6.1 - 2017-05-21\n\n### Changed\n\n- Bump `connect` version\n\n## 3.6.0 - 2017-05-04\n\n### Added\n\n- `expectCt` middleware for setting the `Expect-CT` header\n\n## 3.5.0 - 2017-03-06\n\n### Added\n\n- `csp` now supports the `worker-src` directive\n\n## 3.4.1 - 2017-02-24\n\n### Changed\n\n- Bump `connect` version\n\n## 3.4.0 - 2017-01-13\n\n### Added\n\n- `csp` now supports more `sandbox` directives\n\n## 3.3.0 - 2016-12-31\n\n### Added\n\n- `referrerPolicy` allows `strict-origin` and `strict-origin-when-cross-origin` directives\n\n### Changed\n\n- Bump `connect` version\n\n## 3.2.0 - 2016-12-22\n\n### Added\n\n- `csp` now allows `manifest-src` directive\n\n## 3.1.0 - 2016-11-03\n\n### Added\n\n- `csp` now allows `frame-src` directive\n\n## 3.0.0 - 2016-10-28\n\n### Changed\n\n- `csp` will check your directives for common mistakes and throw errors if it finds them. This can be disabled with `loose: true`.\n- Empty arrays are no longer allowed in `csp`. For source lists (like `script-src` or `object-src`), use the standard `scriptSrc: [\"'none'\"]`. The `sandbox` directive can be `sandbox: true` to block everything.\n- `false` can disable a CSP directive. For example, `scriptSrc: false` is the same as not specifying it.\n- In CSP, `reportOnly: true` no longer requires a `report-uri` to be set.\n- `hsts`'s `maxAge` now defaults to 180 days (instead of 1 day)\n- `hsts`'s `maxAge` parameter is seconds, not milliseconds\n- `hsts` includes subdomains by default\n- `domain` parameter in `frameguard` cannot be empty\n\n### Removed\n\n- `noEtag` option no longer present in `noCache`\n- iOS Chrome `connect-src` workaround in CSP module\n\n## 2.3.0 - 2016-09-30\n\n### Added\n\n- `hpkp` middleware now supports the `includeSubDomains` property with a capital D\n\n### Fixed\n\n- `hpkp` was setting `includeSubdomains` instead of `includeSubDomains`\n\n## 2.2.0 - 2016-09-16\n\n### Added\n\n- `referrerPolicy` middleware\n\n## 2.1.3 - 2016-09-07\n\n### Changed\n\n- Top-level aliases (like `helmet.xssFilter`) are no longer dynamically required\n\n## 2.1.2 - 2016-07-27\n\n### Deprecated\n\n- `nocache`'s `noEtag` option is now deprecated\n\n### Fixed\n\n- `csp` now better handles Firefox on mobile\n\n## 2.1.1 - 2016-06-10\n\n### Changed\n\n- Remove several dependencies from `helmet-csp`\n\n### Fixed\n\n- `frameguard` had a documentation error about its default value\n- `frameguard` docs in main Helmet readme said `frameguard`, not `helmet.frameguard`\n\n## 2.1.0 - 2016-05-18\n\n### Added\n\n- `csp` lets you dynamically set `reportOnly`\n\n## 2.0.0 - 2016-04-29\n\n### Added\n\n- Pass configuration to enable/disable default middlewares\n\n### Changed\n\n- `dnsPrefetchControl` middleware is now enabled by default\n\n### Removed\n\n- No more module aliases. There is now just one way to include each middleware\n- `frameguard` can no longer be initialized with strings; you must use an object\n\n### Fixed\n\n- Make `hpkp` lowercase in documentation\n- Update `hpkp` spec URL in readmes\n- Update `frameguard` header name in readme\n\n## 1.3.0 - 2016-03-01\n\n### Added\n\n- `hpkp` has a `setIf` option to conditionally set the header\n\n## 1.2.0 - 2016-02-29\n\n### Added\n\n- `csp` now has a `browserSniff` option to disable all user-agent sniffing\n\n### Changed\n\n- `frameguard` can now be initialized with options\n- Add `npmignore` file to speed up installs slightly\n\n## 1.1.0 - 2016-01-12\n\n### Added\n\n- Code of conduct\n- `dnsPrefetchControl` middleware\n\n### Fixed\n\n- `csp` readme had syntax errors\n\n## 1.0.2 - 2016-01-08\n\n### Fixed\n\n- `csp` wouldn't recognize `IE Mobile` browsers\n- `csp` had some errors in its readme\n- Main readme had a syntax error\n\n## 1.0.1 - 2015-12-19\n\n### Fixed\n\n- `csp` with no User Agent would cause errors\n\n## 1.0.0 - 2015-12-18\n\n### Added\n\n- `csp` module supports dynamically-generated values\n\n### Changed\n\n- `csp` directives are now under the `directives` key\n- `hpkp`'s `Report-Only` header is now opt-in, not opt-out\n- Tweak readmes of every sub-repo\n\n### Removed\n\n- `crossdomain` middleware\n- `csp` no longer throws errors when some directives aren't quoted (`'self'`, for example)\n- `maxage` option in the `hpkp` middleware\n- `safari5` option from `csp` module\n\n### Fixed\n\n- Old Firefox Content-Security-Policy behavior for `unsafe-inline` and `unsafe-eval`\n- Dynamic `csp` policies is no longer recursive\n\n## 0.15.0 - 2015-11-26\n\n### Changed\n\n- `hpkp` allows a `report-uri` without the `Report-Only` header\n\n## 0.14.0 - 2015-11-01\n\n### Added\n\n- `nocache` now sends the `Surrogate-Control` header\n\n### Changed\n\n- `nocache` no longer contains the `private` directive in the `Cache-Control` header\n\n## 0.13.0 - 2015-10-23\n\n### Added\n\n- `xssFilter` now has a function name\n- Added new CSP docs to readme\n\n### Changed\n\n- HSTS option renamed from `includeSubdomains` to `includeSubDomains`\n\n## 0.11.0 - 2015-09-18\n\n### Added\n\n- `csp` now supports Microsoft Edge\n- CSP Level 2 support\n\n### Changed\n\n- Updated `connect` to 3.4.0\n- Updated `depd` to 1.1.0\n\n### Fixed\n\n- Added `license` key to `csp`'s `package.json`\n- Empty `csp` directives now support every directive, not just `sandbox`\n\n## 0.10.0 - 2015-07-08\n\n### Added\n\n- Add \"Handling CSP violations\" to `csp` readme\n- Add license to `package.json`\n\n### Changed\n\n- `hpkp` had a link to the wrong place in its readme\n- `hpkp` requires 2 or more pins\n\n### Fixed\n\n- `hpkp` might have miscalculated `maxAge` slightly wrong\n\n## 0.9.0 - 2015-04-24\n\n### Changed\n\n- `nocache` adds `private` to its `Cache-Control` directive\n- Added a description to `package.json`\n\n## 0.8.0 - 2015-04-21\n\n### Changed\n\n- Removed hefty Lodash dependency from HSTS and CSP\n- Updated string detection module in Frameguard\n- Changed readme slightly to better reflect project's focus\n\n### Deprecated\n\n- Deprecated `crossdomain` middleware\n\n### Removed\n\n- `crossdomain` is no longer a default middleware\n\n## 0.7.1 - 2015-03-23\n\n### Changed\n\n- Updated all outdated dependencies (insofar as possible)\n- HSTS now uses Lodash like all the rest of the libraries\n\n## 0.7.0 - 2015-03-05\n\n### Added\n\n- `hpkp` middleware\n\n### Changed\n\n- Travis CI should test 0.10 and 0.12\n- Minor code cleanup\n\n## 0.6.2 - 2015-03-01\n\n### Changed\n\n- Improved `xssFilter` performance\n- Updated Lodash versions\n\n## 0.6.1 - 2015-02-13\n\n### Added\n\n- \"Other recommended modules\" in README\n\n### Changed\n\n- Updated Lodash version\n\n### Fixed\n\n- `frameguard` middleware exported a function called `xframe`\n\n## 0.6.0 - 2015-01-21\n\n### Added\n\n- You can disable `csp` for Android\n\n### Fixed\n\n- `csp` on Chrome Mobile on Android and iOS\n\n## 0.5.4 - 2014-12-21\n\n### Changed\n\n- `nocache` should force revalidation\n\n## 0.5.3 - 2014-12-08\n\n### Changed\n\n- `platform` version in CSP and X-XSS-Protection\n\n### Fixed\n\n- Updated bad wording in frameguard docs\n\n## 0.5.2 - 2014-11-16\n\n### Changed\n\n- Updated Connect version\n\n### Fixed\n\n- Fixed minor `csp` bugfixes\n\n## 0.5.1 - 2014-11-09\n\n### Changed\n\n- Updated URLs in `package.json` for new URL\n\n### Fixed\n\n- CSP would set all headers forever after receiving an unknown user agent\n\n## 0.5.0 - 2014-10-28\n\n### Added\n\n- Most middlewares have some aliases now\n\n### Changed\n\n- `xframe` now called `frameguard` (though `xframe` still works)\n- `frameguard` chooses sameorigin by default\n- `frameguard` understands \"SAME-ORIGIN\" in addition to \"SAMEORIGIN\"\n- `nocache` removed from default middleware stack\n- Middleware split out into their own modules\n- Documentation\n- Updated supported Node version to at least 0.10.0\n- Bumped Connect version\n\n### Removed\n\n- Deprecation warnings\n\n### Fixed\n\n- Readme link was broken\n\n## 0.4.2 - 2014-10-16\n\n### Added\n\n- Support preload in HSTS header\n\n## 0.4.1 - 2014-08-24\n\n### Added\n\n- Use [helmet-crossdomain](https://github.com/helmetjs/crossdomain) to test the waters\n- 2 spaces instead of 4 throughout the code\n\n## 0.4.0 - 2014-07-17\n\n### Added\n\n- `nocache` now sets the Expires and Pragma headers\n- `nocache` now allows you to crush ETags\n\n### Changed\n\n- Improved the docs for nosniff\n- Reverted HSTS behavior of requiring a specified max-age\n\n### Fixed\n\n- Allow HSTS to have a max-age of 0\n\n## 0.3.2 - 2014-06-30\n\n### Added\n\n- All middleware functions are named\n- Throw error with non-positive HSTS max-age\n\n### Changed\n\n- Added semicolons in README\n- Make some Errors more specific\n\n### Removed\n\n- Removed all comment headers; refer to the readme\n\n### Fixed\n\n- `helmet()` was having issues\n- Fixed Syntax errors in README\n\nThis changelog was created after the release of 0.3.1.\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our community include:\n\n- Demonstrating empathy and kindness toward other people\n- Being respectful of differing opinions, viewpoints, and experiences\n- Giving and gracefully accepting constructive feedback\n- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\n- Focusing on what is best not just for us as individuals, but for the overall community\n\nExamples of unacceptable behavior include:\n\n- The use of sexualized language or imagery, and sexual attention or advances of any kind\n- Trolling, insulting or derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or email address, without their explicit permission\n- Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [evanhahn.com/contact](https://evanhahn.com/contact). All complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the reporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of actions.\n\n**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at <https://www.contributor-covenant.org/faq>. Translations are available at <https://www.contributor-covenant.org/translations>.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Helmet\n\nHelmet welcomes contributors! This guide should help you submit issues and pull requests.\n\n## Got a question, problem, or feature request?\n\nThe documentation and [Stack Overflow](https://stackoverflow.com/questions/tagged/helmet.js) are good places to start.\n\nFeel free to [add an issue](https://github.com/helmetjs/helmet/issues) or [contact the maintainer](https://evanhahn.com/contact) if those don't help!\n\n## Want to submit a change?\n\nIf you're not sure whether your change will be welcomed, [add an issue](https://github.com/helmetjs/helmet/issues) to ask.\n\nOnce you're ready to make your change, make a pull request. If you're having trouble making a pull request (it's tricky!), check out [GitHub's guide](https://help.github.com/articles/using-pull-requests/) or add an issue. We'll make it work!\n\nPlease avoid using LLM/AI tools for work on Helmet.js. This is because (1) LLM-produced code may have copyright issues (2) LLM-based code is often lower quality, raising the bar for maintainers (3) LLMs have many ethical issues which this project wants to avoid.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2012-2026 Evan Hahn, Adam Baldwin\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Helmet\n\nHelmet helps secure Node/Express apps. It sets HTTP response headers such as `Content-Security-Policy` and `Strict-Transport-Security`. It aims to be quick to integrate and be low maintenance afterward.\n\n## Quick start\n\n```javascript\nimport helmet from \"helmet\";\n\nconst app = express();\n\napp.use(helmet());\n```\n\nThis will set 13 HTTP response headers in your app.\n\n[Helmet can also be used in standalone Node.js, or with other frameworks.](https://helmetjs.github.io/faq/use-without-express/)\n\n## Configuration\n\nEach header can be disabled. To disable a header:\n\n```js\n// Disable the Content-Security-Policy and X-Download-Options headers\napp.use(\n  helmet({\n    contentSecurityPolicy: false,\n    xDownloadOptions: false,\n  }),\n);\n```\n\nTo configure a header, pass header-specific options:\n\n```js\n// Configure the Content-Security-Policy header.\napp.use(\n  helmet({\n    contentSecurityPolicy: {\n      directives: {\n        \"script-src\": [\"'self'\", \"example.com\"],\n      },\n    },\n  }),\n);\n```\n\n## HTTP header reference\n\n<details id=\"content-security-policy\">\n<summary><code>Content-Security-Policy</code></summary>\n\nDefault:\n\n```http\nContent-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\n```\n\nThe `Content-Security-Policy` header mitigates a large number of attacks, such as [cross-site scripting][XSS]. See [MDN's introductory article on Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).\n\nThis header is powerful but likely requires some configuration for your specific app.\n\nTo configure this header, pass an object with a nested `directives` object. Each key is a directive name in camel case (such as `defaultSrc`) or kebab case (such as `default-src`). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects.\n\n```javascript\n// Sets all of the defaults, but overrides `script-src`\n// and disables the default `style-src`.\napp.use(\n  helmet({\n    contentSecurityPolicy: {\n      directives: {\n        \"script-src\": [\"'self'\", \"example.com\"],\n        \"style-src\": null,\n      },\n    },\n  }),\n);\n```\n\n```js\n// Sets the `script-src` directive to\n// \"'self' 'nonce-e33cc...'\"\n// (or similar)\napp.use((req, res, next) => {\n  res.locals.cspNonce = crypto.randomBytes(32).toString(\"hex\");\n  next();\n});\napp.use(\n  helmet({\n    contentSecurityPolicy: {\n      directives: {\n        scriptSrc: [\"'self'\", (req, res) => `'nonce-${res.locals.cspNonce}'`],\n      },\n    },\n  }),\n);\n```\n\nThese directives are merged into a default policy, which you can disable by setting `useDefaults` to `false`.\n\n```javascript\n// Sets \"Content-Security-Policy: default-src 'self';\n// script-src 'self' example.com;object-src 'none';\n// upgrade-insecure-requests\"\napp.use(\n  helmet({\n    contentSecurityPolicy: {\n      useDefaults: false,\n      directives: {\n        defaultSrc: [\"'self'\"],\n        scriptSrc: [\"'self'\", \"example.com\"],\n        objectSrc: [\"'none'\"],\n        upgradeInsecureRequests: [],\n      },\n    },\n  }),\n);\n```\n\nYou can get the default directives object with `helmet.contentSecurityPolicy.getDefaultDirectives()`. Here is the default policy (formatted for readability):\n\n```\ndefault-src 'self';\nbase-uri 'self';\nfont-src 'self' https: data:;\nform-action 'self';\nframe-ancestors 'self';\nimg-src 'self' data:;\nobject-src 'none';\nscript-src 'self';\nscript-src-attr 'none';\nstyle-src 'self' https: 'unsafe-inline';\nupgrade-insecure-requests\n```\n\nThe `default-src` directive can be explicitly disabled by setting its value to `helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc`, but this is not recommended.\n\nYou can set the [`Content-Security-Policy-Report-Only`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) instead:\n\n```javascript\n// Sets the Content-Security-Policy-Report-Only header\napp.use(\n  helmet({\n    contentSecurityPolicy: {\n      directives: {\n        /* ... */\n      },\n      reportOnly: true,\n    },\n  }),\n);\n```\n\n`upgrade-insecure-requests`, a directive that causes browsers to upgrade HTTP to HTTPS, is set by default. You may wish to avoid this in development, as you may not be developing with HTTPS. Notably, Safari will upgrade `http://localhost` to `https://localhost`, which can cause problems. To work around this, you may wish to disable the `upgrade-insecure-requests` directive in development. For example:\n\n```js\nconst isDevelopment = app.get(\"env\") === \"development\";\n\napp.use(\n  helmet({\n    contentSecurityPolicy: {\n      directives: {\n        // Disable upgrade-insecure-requests in development.\n        \"upgrade-insecure-requests\": isDevelopment ? null : [],\n      },\n    },\n  }),\n);\n```\n\nHelmet performs very little validation on your CSP. You should rely on CSP checkers like [CSP Evaluator](https://csp-evaluator.withgoogle.com/) instead.\n\nTo disable the `Content-Security-Policy` header:\n\n```js\napp.use(\n  helmet({\n    contentSecurityPolicy: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.contentSecurityPolicy())`.\n\n</details>\n\n<details id=\"cross-origin-embedder-policy\">\n<summary><code>Cross-Origin-Embedder-Policy</code></summary>\n\nThis header is not set by default.\n\nThe `Cross-Origin-Embedder-Policy` header helps control what resources can be loaded cross-origin. See [MDN's article on this header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy) for more.\n\n```js\n// Helmet does not set Cross-Origin-Embedder-Policy\n// by default.\napp.use(helmet());\n\n// Sets \"Cross-Origin-Embedder-Policy: require-corp\"\napp.use(helmet({ crossOriginEmbedderPolicy: true }));\n\n// Sets \"Cross-Origin-Embedder-Policy: credentialless\"\napp.use(helmet({ crossOriginEmbedderPolicy: { policy: \"credentialless\" } }));\n```\n\nYou can use this as standalone middleware with `app.use(helmet.crossOriginEmbedderPolicy())`.\n\n</details>\n\n<details id=\"cross-origin-opener-policy\">\n<summary><code>Cross-Origin-Opener-Policy</code></summary>\n\nDefault:\n\n```http\nCross-Origin-Opener-Policy: same-origin\n```\n\nThe `Cross-Origin-Opener-Policy` header helps process-isolate your page. For more, see [MDN's article on this header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy).\n\n```js\n// Sets \"Cross-Origin-Opener-Policy: same-origin\"\napp.use(helmet());\n\n// Sets \"Cross-Origin-Opener-Policy: same-origin-allow-popups\"\napp.use(\n  helmet({\n    crossOriginOpenerPolicy: { policy: \"same-origin-allow-popups\" },\n  }),\n);\n```\n\nTo disable the `Cross-Origin-Opener-Policy` header:\n\n```js\napp.use(\n  helmet({\n    crossOriginOpenerPolicy: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.crossOriginOpenerPolicy())`.\n\n</details>\n\n<details id=\"cross-origin-resource-policy\">\n<summary><code>Cross-Origin-Resource-Policy</code></summary>\n\nDefault:\n\n```http\nCross-Origin-Resource-Policy: same-origin\n```\n\nThe `Cross-Origin-Resource-Policy` header blocks others from loading your resources cross-origin in some cases. For more, see [\"Consider deploying Cross-Origin Resource Policy\"](https://resourcepolicy.fyi/) and [MDN's article on this header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy).\n\n```js\n// Sets \"Cross-Origin-Resource-Policy: same-origin\"\napp.use(helmet());\n\n// Sets \"Cross-Origin-Resource-Policy: same-site\"\napp.use(helmet({ crossOriginResourcePolicy: { policy: \"same-site\" } }));\n```\n\nTo disable the `Cross-Origin-Resource-Policy` header:\n\n```js\napp.use(\n  helmet({\n    crossOriginResourcePolicy: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.crossOriginResourcePolicy())`.\n\n</details>\n\n<details id=\"origin-agent-cluster\">\n<summary><code>Origin-Agent-Cluster</code></summary>\n\nDefault:\n\n```http\nOrigin-Agent-Cluster: ?1\n```\n\nThe `Origin-Agent-Cluster` header provides a mechanism to allow web applications to isolate their origins from other processes. Read more about it [in the spec](https://html.spec.whatwg.org/multipage/browsers.html#origin-keyed-agent-clusters).\n\nThis header takes no options and is set by default.\n\n```js\n// Sets \"Origin-Agent-Cluster: ?1\"\napp.use(helmet());\n```\n\nTo disable the `Origin-Agent-Cluster` header:\n\n```js\napp.use(\n  helmet({\n    originAgentCluster: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.originAgentCluster())`.\n\n</details>\n\n<details id=\"referrer-policy\">\n<summary><code>Referrer-Policy</code></summary>\n\nDefault:\n\n```http\nReferrer-Policy: no-referrer\n```\n\nThe `Referrer-Policy` header which controls what information is set in [the `Referer` request header][Referer]. See [\"Referer header: privacy and security concerns\"](https://developer.mozilla.org/en-US/docs/Web/Security/Referer_header:_privacy_and_security_concerns) and [the header's documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) on MDN for more.\n\n```js\n// Sets \"Referrer-Policy: no-referrer\"\napp.use(helmet());\n```\n\n`policy` is a string or array of strings representing the policy. If passed as an array, it will be joined with commas, which is useful when setting [a fallback policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#Specifying_a_fallback_policy). It defaults to `no-referrer`.\n\n```js\n// Sets \"Referrer-Policy: no-referrer\"\napp.use(\n  helmet({\n    referrerPolicy: {\n      policy: \"no-referrer\",\n    },\n  }),\n);\n\n// Sets \"Referrer-Policy: origin,unsafe-url\"\napp.use(\n  helmet({\n    referrerPolicy: {\n      policy: [\"origin\", \"unsafe-url\"],\n    },\n  }),\n);\n```\n\nTo disable the `Referrer-Policy` header:\n\n```js\napp.use(\n  helmet({\n    referrerPolicy: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.referrerPolicy())`.\n\n</details>\n\n<details id=\"strict-transport-security\">\n<summary><code>Strict-Transport-Security</code></summary>\n\nDefault:\n\n```http\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n```\n\nThe `Strict-Transport-Security` header tells browsers to prefer HTTPS instead of insecure HTTP. See [the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) for more.\n\n```js\n// Sets \"Strict-Transport-Security: max-age=31536000; includeSubDomains\"\napp.use(helmet());\n```\n\n`maxAge` is the number of seconds browsers should remember to prefer HTTPS. If passed a non-integer, the value is rounded down. It defaults to 365 days.\n\n`includeSubDomains` is a boolean which dictates whether to include the `includeSubDomains` directive, which makes this policy extend to subdomains. It defaults to `true`.\n\n`preload` is a boolean. If true, it adds the `preload` directive, expressing intent to add your HSTS policy to browsers. See [the \"Preloading Strict Transport Security\" section on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#Preloading_Strict_Transport_Security) for more. It defaults to `false`.\n\n```js\n// Sets \"Strict-Transport-Security: max-age=123456; includeSubDomains\"\napp.use(\n  helmet({\n    strictTransportSecurity: {\n      maxAge: 123456,\n    },\n  }),\n);\n\n// Sets \"Strict-Transport-Security: max-age=123456\"\napp.use(\n  helmet({\n    strictTransportSecurity: {\n      maxAge: 123456,\n      includeSubDomains: false,\n    },\n  }),\n);\n\n// Sets \"Strict-Transport-Security: max-age=123456; includeSubDomains; preload\"\napp.use(\n  helmet({\n    strictTransportSecurity: {\n      maxAge: 63072000,\n      preload: true,\n    },\n  }),\n);\n```\n\nTo disable the `Strict-Transport-Security` header:\n\n```js\napp.use(\n  helmet({\n    strictTransportSecurity: false,\n  }),\n);\n```\n\nYou may wish to disable this header for local development, as it can make your browser force redirects from `http://localhost` to `https://localhost`, which may not be desirable if you develop multiple apps using `localhost`. See [this issue](https://github.com/helmetjs/helmet/issues/451) for more discussion.\n\nYou can use this as standalone middleware with `app.use(helmet.strictTransportSecurity())`.\n\n</details>\n\n<details id=\"x-content-type-options\">\n<summary><code>X-Content-Type-Options</code></summary>\n\nDefault:\n\n```http\nX-Content-Type-Options: nosniff\n```\n\nThe `X-Content-Type-Options` mitigates [MIME type sniffing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#MIME_sniffing) which can cause security issues. See [documentation for this header on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) for more.\n\nThis header takes no options and is set by default.\n\n```js\n// Sets \"X-Content-Type-Options: nosniff\"\napp.use(helmet());\n```\n\nTo disable the `X-Content-Type-Options` header:\n\n```js\napp.use(\n  helmet({\n    xContentTypeOptions: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xContentTypeOptions())`.\n\n</details>\n\n<details id=\"x-dns-prefetch-control\">\n<summary><code>X-DNS-Prefetch-Control</code></summary>\n\nDefault:\n\n```http\nX-DNS-Prefetch-Control: off\n```\n\nThe `X-DNS-Prefetch-Control` header helps control DNS prefetching, which can improve user privacy at the expense of performance. See [documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control) for more.\n\n```js\n// Sets \"X-DNS-Prefetch-Control: off\"\napp.use(helmet());\n```\n\n`allow` is a boolean dictating whether to enable DNS prefetching. It defaults to `false`.\n\nExamples:\n\n```js\n// Sets \"X-DNS-Prefetch-Control: off\"\napp.use(\n  helmet({\n    xDnsPrefetchControl: { allow: false },\n  }),\n);\n\n// Sets \"X-DNS-Prefetch-Control: on\"\napp.use(\n  helmet({\n    xDnsPrefetchControl: { allow: true },\n  }),\n);\n```\n\nTo disable the `X-DNS-Prefetch-Control` header and use the browser's default value:\n\n```js\napp.use(\n  helmet({\n    xDnsPrefetchControl: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xDnsPrefetchControl())`.\n\n</details>\n\n<details id=\"x-download-options\">\n<summary><code>X-Download-Options</code></summary>\n\nDefault:\n\n```http\nX-Download-Options: noopen\n```\n\nThe `X-Download-Options` header is specific to Internet Explorer 8. It forces potentially-unsafe downloads to be saved, mitigating execution of HTML in your site's context. For more, see [this old post on MSDN](https://learn.microsoft.com/en-us/archive/blogs/ie/ie8-security-part-v-comprehensive-protection).\n\nThis header takes no options and is set by default.\n\n```js\n// Sets \"X-Download-Options: noopen\"\napp.use(helmet());\n```\n\nTo disable the `X-Download-Options` header:\n\n```js\napp.use(\n  helmet({\n    xDownloadOptions: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xDownloadOptions())`.\n\n</details>\n\n<details id=\"x-frame-options\">\n<summary><code>X-Frame-Options</code></summary>\n\nDefault:\n\n```http\nX-Frame-Options: SAMEORIGIN\n```\n\nThe legacy `X-Frame-Options` header to help you mitigate [clickjacking attacks](https://en.wikipedia.org/wiki/Clickjacking). This header is superseded by [the `frame-ancestors` Content Security Policy directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) but is still useful on old browsers or if no CSP is used. For more, see [the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options).\n\n```js\n// Sets \"X-Frame-Options: SAMEORIGIN\"\napp.use(helmet());\n```\n\n`action` is a string that specifies which directive to use—either `DENY` or `SAMEORIGIN`. (A legacy directive, `ALLOW-FROM`, is not supported by Helmet. [Read more here.](https://helmetjs.github.io/faq/x-frame-options-allow-from-directive/)) It defaults to `SAMEORIGIN`.\n\nExamples:\n\n```js\n// Sets \"X-Frame-Options: DENY\"\napp.use(\n  helmet({\n    xFrameOptions: { action: \"deny\" },\n  }),\n);\n\n// Sets \"X-Frame-Options: SAMEORIGIN\"\napp.use(\n  helmet({\n    xFrameOptions: { action: \"sameorigin\" },\n  }),\n);\n```\n\nTo disable the `X-Frame-Options` header:\n\n```js\napp.use(\n  helmet({\n    xFrameOptions: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xFrameOptions())`.\n\n</details>\n\n<details id=\"x-permitted-cross-domain-policies\">\n<summary><code>X-Permitted-Cross-Domain-Policies</code></summary>\n\nDefault:\n\n```http\nX-Permitted-Cross-Domain-Policies: none\n```\n\nThe `X-Permitted-Cross-Domain-Policies` header tells some clients (mostly Adobe products) your domain's policy for loading cross-domain content. See [the description on OWASP](https://owasp.org/www-project-secure-headers/) for more.\n\n```js\n// Sets \"X-Permitted-Cross-Domain-Policies: none\"\napp.use(helmet());\n```\n\n`permittedPolicies` is a string that must be `\"none\"`, `\"master-only\"`, `\"by-content-type\"`, or `\"all\"`. It defaults to `\"none\"`.\n\nExamples:\n\n```js\n// Sets \"X-Permitted-Cross-Domain-Policies: none\"\napp.use(\n  helmet({\n    xPermittedCrossDomainPolicies: {\n      permittedPolicies: \"none\",\n    },\n  }),\n);\n\n// Sets \"X-Permitted-Cross-Domain-Policies: by-content-type\"\napp.use(\n  helmet({\n    xPermittedCrossDomainPolicies: {\n      permittedPolicies: \"by-content-type\",\n    },\n  }),\n);\n```\n\nTo disable the `X-Permitted-Cross-Domain-Policies` header:\n\n```js\napp.use(\n  helmet({\n    xPermittedCrossDomainPolicies: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xPermittedCrossDomainPolicies())`.\n\n</details>\n\n<details id=\"x-powered-by\">\n<summary><code>X-Powered-By</code></summary>\n\nDefault: the `X-Powered-By` header, if present, is removed.\n\nHelmet removes the `X-Powered-By` header, which is set by default in Express and some other frameworks. Removing the header offers very limited security benefits (see [this discussion](https://github.com/expressjs/express/pull/2813#issuecomment-159270428)) and is mostly removed to save bandwidth, but may thwart simplistic attackers.\n\nNote: [Express has a built-in way to disable the `X-Powered-By` header](https://stackoverflow.com/a/12484642/804100), which you may wish to use instead.\n\nThe removal of this header takes no options. The header is removed by default.\n\nTo disable this behavior:\n\n```js\n// Not required, but recommended for Express users:\napp.disable(\"x-powered-by\");\n\n// Ask Helmet to ignore the X-Powered-By header.\napp.use(\n  helmet({\n    xPoweredBy: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xPoweredBy())`.\n\n</details>\n\n<details id=\"x-xss-protection\">\n<summary><code>X-XSS-Protection</code></summary>\n\nDefault:\n\n```http\nX-XSS-Protection: 0\n```\n\nHelmet disables browsers' buggy cross-site scripting filter by setting the legacy `X-XSS-Protection` header to `0`. See [discussion about disabling the header here](https://github.com/helmetjs/helmet/issues/230) and [documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection).\n\nThis header takes no options and is set by default.\n\nTo disable the `X-XSS-Protection` header:\n\n```js\n// This is not recommended.\napp.use(\n  helmet({\n    xXssProtection: false,\n  }),\n);\n```\n\nYou can use this as standalone middleware with `app.use(helmet.xXssProtection())`.\n\n</details>\n\n[Referer]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer\n[MIME sniffing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing\n[Clickjacking]: https://en.wikipedia.org/wiki/Clickjacking\n[XSS]: https://developer.mozilla.org/en-US/docs/Glossary/Cross-site_scripting\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security issue reporting & disclosure process\n\nPlease reach out if you think you've found a security issue.\n\nEmail Evan Hahn at <me@evanhahn.com>, on Signal at [EvanHahn.64](https://signal.me/#eu/vDide_HmUgHnNa0usMXq8oHAA0gnl5dzCqDeHyXhkeIbIiOcPVhCZKXIZteSqoc8), or [in other ways](https://evanhahn.com/contact).\n\nMy playbook for security issues:\n\n- Acknowledge and address the concern as soon as possible\n- Issue advisories (CVEs, for example) as needed. Public disclosure may be embargoed to give people time to update\n- Consider patching non-current major versions depending on popularity and severity\n"
  },
  {
    "path": "build/build-package.ts",
    "content": "import rollupTypescript from \"@rollup/plugin-typescript\";\nimport zopfli from \"node-zopfli\";\nimport * as fsOriginal from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { pipeline } from \"node:stream\";\nimport { fileURLToPath } from \"node:url\";\nimport { promisify } from \"node:util\";\nimport * as zlib from \"node:zlib\";\nimport prettier from \"prettier\";\nimport { type RollupBuild, rollup } from \"rollup\";\nimport rollupDts from \"rollup-plugin-dts\";\nimport { npm } from \"./helpers.js\";\n\nconst fs = fsOriginal.promises;\nconst pipe = promisify(pipeline);\n\n// This shaves a few bytes off the built files while still keeping them readable.\n// When testing on 4f550aab7ccf00a6dfe686d57195268b3ef06b1a, it reduces the tarball size by about 100 bytes.\n// This should help installation performance slightly.\nconst PRETTIER_PREPACK_CRUSH_OPTIONS: prettier.Options = {\n  printWidth: 2000,\n  trailingComma: \"none\",\n  useTabs: true,\n  arrowParens: \"avoid\",\n  bracketSpacing: false,\n  semi: false,\n};\n\nconst rootDir = path.join(path.dirname(fileURLToPath(import.meta.url)), \"..\");\nconst testFiles = path.join(rootDir, \"test\", \"**\");\n\n/**\n * Build a Helmet package into a tarball ready to be published with `npm publish`.\n */\nexport async function buildAndPack(\n  middlewareToBuild?: string,\n): Promise<string> {\n  let entry: string;\n  let esm: boolean;\n  let packageOverrides: Record<string, unknown>;\n  let filesToCopy: readonly string[];\n\n  if (middlewareToBuild) {\n    const middlewareDir = path.join(rootDir, \"middlewares\", middlewareToBuild);\n    entry = path.join(middlewareDir, \"index.ts\");\n    esm = false;\n    packageOverrides = await readJsonObject(\n      path.join(middlewareDir, \"package-overrides.json\"),\n    );\n    filesToCopy = [\n      path.join(rootDir, \"LICENSE\"),\n      path.join(middlewareDir, \"README.md\"),\n      path.join(middlewareDir, \"CHANGELOG.md\"),\n    ];\n  } else {\n    entry = path.join(rootDir, \"index.ts\");\n    esm = true;\n    packageOverrides = {};\n    filesToCopy = [\n      path.join(rootDir, \"LICENSE\"),\n      path.join(rootDir, \"README.md\"),\n      path.join(rootDir, \"CHANGELOG.md\"),\n      path.join(rootDir, \"SECURITY.md\"),\n    ];\n  }\n\n  const distDir = await temporaryDirectory();\n\n  await Promise.all([\n    buildCjs({ entry, distDir }),\n    ...(esm ? [buildMjs({ entry, distDir })] : []),\n    buildTypes({ esm, entry, distDir }),\n    buildPackageJson({ esm, packageOverrides, distDir }),\n    copyStaticFiles({ filesToCopy, distDir }),\n  ]);\n\n  await prePackCrush(distDir);\n\n  const npmPackedTarball = await pack(distDir);\n\n  const crushedTarball = await postPackCrush(npmPackedTarball);\n\n  return crushedTarball;\n}\n\nfunction temporaryDirectory(): Promise<string> {\n  return fs.mkdtemp(path.join(os.tmpdir(), \"helmet\"));\n}\n\nasync function buildCjs({\n  entry,\n  distDir,\n}: Readonly<{ entry: string; distDir: string }>) {\n  const outputPath = path.join(distDir, \"index.cjs\");\n\n  console.log(`Building ${outputPath}...`);\n\n  const bundle = await rollupForJs({ entry, distDir });\n\n  await bundle.write({\n    file: outputPath,\n    exports: \"named\",\n    format: \"cjs\",\n    generatedCode: \"es2015\",\n    outro: [\n      \"module.exports = exports.default;\",\n      // Some bundlers import with CommonJS but then pull `default` off.\n      \"module.exports.default = module.exports;\",\n    ].join(\"\\n\"),\n  });\n\n  await bundle.close();\n\n  console.log(`Built ${outputPath}.`);\n}\n\nasync function buildMjs({\n  entry,\n  distDir,\n}: Readonly<{ entry: string; distDir: string }>) {\n  const outputPath = path.join(distDir, \"index.mjs\");\n\n  console.log(`Building ${outputPath}...`);\n\n  const bundle = await rollupForJs({ entry, distDir });\n\n  await bundle.write({\n    file: outputPath,\n    format: \"esm\",\n    generatedCode: \"es2015\",\n  });\n\n  await bundle.close();\n\n  console.log(`Built ${outputPath}.`);\n}\n\nfunction rollupForJs({\n  entry,\n  distDir,\n}: Readonly<{ entry: string; distDir: string }>): Promise<RollupBuild> {\n  return rollup({\n    input: entry,\n    plugins: [\n      rollupTypescript({\n        outDir: distDir,\n        exclude: [testFiles],\n      }),\n    ],\n  });\n}\n\nasync function buildTypes({\n  esm,\n  entry,\n  distDir,\n}: Readonly<{ esm: boolean; entry: string; distDir: string }>) {\n  console.log(\"Building types...\");\n\n  const bundle = await rollup({\n    input: entry,\n    external: [\"node:http\"],\n    plugins: [rollupDts()],\n  });\n\n  await Promise.all([\n    (async () => {\n      const cjsPath = path.join(distDir, \"index.d.cts\");\n      await bundle.write({\n        file: cjsPath,\n        format: \"commonjs\",\n      });\n      console.log(`Built ${cjsPath}.`);\n    })(),\n    (async () => {\n      if (!esm) {\n        return;\n      }\n      const esmPath = path.join(distDir, \"index.d.mts\");\n      await bundle.write({\n        file: esmPath,\n        format: \"esm\",\n      });\n      console.log(`Built ${esmPath}.`);\n    })(),\n  ]);\n\n  await bundle.close();\n}\n\nasync function buildPackageJson({\n  esm,\n  packageOverrides,\n  distDir,\n}: Readonly<{\n  esm: boolean;\n  packageOverrides: Readonly<Record<string, unknown>>;\n  distDir: string;\n}>) {\n  const outputPath = path.join(distDir, \"package.json\");\n\n  console.log(`Building ${outputPath}...`);\n\n  const devPackageJson = await readJsonObject(\n    path.join(rootDir, \"package.json\"),\n  );\n\n  const packageJson = {\n    name: \"helmet\",\n    description: \"help secure Express/Connect apps with various HTTP headers\",\n    version: devPackageJson.version,\n    author: \"Adam Baldwin <adam@npmjs.com> (https://evilpacket.net)\",\n    contributors: [\"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\"],\n    homepage: \"https://helmetjs.github.io/\",\n    bugs: {\n      url: \"https://github.com/helmetjs/helmet/issues\",\n      email: \"me@evanhahn.com\",\n    },\n    repository: {\n      type: \"git\",\n      url: \"git://github.com/helmetjs/helmet.git\",\n    },\n    funding: \"https://github.com/sponsors/EvanHahn\",\n    license: \"MIT\",\n    keywords: [\n      \"express\",\n      \"security\",\n      \"headers\",\n      \"backend\",\n      \"content-security-policy\",\n      \"cross-origin-embedder-policy\",\n      \"cross-origin-opener-policy\",\n      \"cross-origin-resource-policy\",\n      \"origin-agent-cluster\",\n      \"referrer-policy\",\n      \"strict-transport-security\",\n      \"x-content-type-options\",\n      \"x-dns-prefetch-control\",\n      \"x-download-options\",\n      \"x-frame-options\",\n      \"x-permitted-cross-domain-policies\",\n      \"x-powered-by\",\n      \"x-xss-protection\",\n    ],\n    engines: devPackageJson.engines,\n    exports: {\n      ...(esm ? { import: \"./index.mjs\" } : {}),\n      require: \"./index.cjs\",\n    },\n    // All supported versions of Node handle `exports`, but some build tools\n    // still use `main`, so we keep it around.\n    main: \"./index.cjs\",\n\n    // Support old TypeScript versions.\n    types: \"./index.d.cts\",\n\n    ...packageOverrides,\n  };\n\n  await fs.writeFile(outputPath, JSON.stringify(packageJson));\n\n  console.log(`Built ${outputPath}.`);\n}\n\nasync function readJsonObject(\n  path: fsOriginal.PathLike,\n): Promise<Record<string, unknown>> {\n  const result: unknown = JSON.parse(await fs.readFile(path, \"utf8\"));\n  if (typeof result !== \"object\" || result === null) {\n    throw new Error(\"Got a non-object from JSON.parse()\");\n  }\n  return result as Record<string, unknown>;\n}\n\nasync function copyStaticFiles({\n  filesToCopy,\n  distDir,\n}: Readonly<{ filesToCopy: readonly string[]; distDir: string }>) {\n  await Promise.all(\n    filesToCopy.map(async (source) => {\n      const basename = path.basename(source);\n      const dest = path.join(distDir, basename);\n      console.log(`Copying ${source} to ${dest}...`);\n      await fs.copyFile(source, dest);\n      console.log(`Copied ${source} to ${dest}.`);\n    }),\n  );\n}\n\nasync function prePackCrush(distDir: string): Promise<void> {\n  const files = (await fs.readdir(distDir))\n    .map((file) => path.join(distDir, file))\n    .filter((file) => path.extname(file) !== \".md\");\n\n  await Promise.all(\n    files.map(async (file) => {\n      const prettierInfo = await prettier.getFileInfo(file);\n      if (!prettierInfo.inferredParser) {\n        return;\n      }\n\n      console.log(`Crushing ${file}...`);\n\n      const oldContents = await fs.readFile(file, { encoding: \"utf8\" });\n\n      const newContents = await prettier.format(oldContents, {\n        filepath: file,\n        ...PRETTIER_PREPACK_CRUSH_OPTIONS,\n      });\n\n      await fs.writeFile(file, newContents, { encoding: \"utf8\" });\n\n      console.log(`Crushed ${file}.`);\n    }),\n  );\n}\n\nasync function pack(distDir: string): Promise<string> {\n  await npm([\"pack\"], { cwd: distDir });\n\n  const tempDirFiles = await fs.readdir(distDir);\n  const tarballName = tempDirFiles.find(\n    (file) => file.startsWith(\"helmet-\") && file.endsWith(\".tgz\"),\n  );\n  if (!tarballName) {\n    throw new Error(\n      \"Couldn't find helmet tarball in temp directory. Build is not set up correctly\",\n    );\n  }\n\n  return path.join(distDir, tarballName);\n}\n\nasync function postPackCrush(originalTarGz: string): Promise<string> {\n  const originalSize = (await fs.stat(originalTarGz)).size;\n  console.log(`Crushing ${originalTarGz} (size: ${originalSize})...`);\n\n  const crushedTarGz = originalTarGz.replace(\".tgz\", \".crushed.tgz\");\n  const readOriginal = fsOriginal.createReadStream(originalTarGz);\n  const gunzip = zlib.createGunzip();\n  const gzip = zopfli.createGzip({ numiterations: 100 });\n  const writeCrushed = fsOriginal.createWriteStream(crushedTarGz);\n\n  await pipe(readOriginal, gunzip, gzip, writeCrushed);\n\n  const crushedSize = (await fs.stat(crushedTarGz)).size;\n  const savings = originalSize - crushedSize;\n\n  if (savings < 0) {\n    console.log(\"Original tarball was smaller\");\n    return originalTarGz;\n  } else {\n    const ratio = crushedSize / originalSize;\n    console.log(\n      `Crushed into ${crushedTarGz}. Size: ${crushedSize}. Savings: ${savings} bytes (result is ${Math.round(\n        ratio * 100,\n      )}% the size)`,\n    );\n    return crushedTarGz;\n  }\n}\n\nconst isMain =\n  import.meta.url.startsWith(\"file:\") &&\n  process.argv[1] === fileURLToPath(import.meta.url);\nif (isMain) {\n  if (process.argv.length > 3) {\n    throw new Error(\"Too many arguments\");\n  }\n\n  const middlewareToBuild = process.argv[2];\n  buildAndPack(middlewareToBuild)\n    .then((finalTarballPath) => {\n      console.log(finalTarballPath);\n    })\n    .catch((err) => {\n      console.error(err);\n      process.exit(1);\n    });\n}\n"
  },
  {
    "path": "build/helpers.ts",
    "content": "import * as childProcess from \"node:child_process\";\n\nexport const npm = (\n  args: readonly string[],\n  { cwd }: Readonly<{ cwd: string }>,\n): Promise<void> =>\n  new Promise((resolve, reject) => {\n    const proc = childProcess.spawn(\"npm\", args, {\n      cwd,\n      stdio: [\"inherit\", \"ignore\", \"inherit\"],\n    });\n    proc.on(\"close\", (code) => {\n      if (code === 0) {\n        resolve();\n      } else {\n        reject(new Error(`npm ${args.join(\" \")} exited with code ${code}`));\n      }\n    });\n  });\n"
  },
  {
    "path": "eslint.config.js",
    "content": "import pluginJs from \"@eslint/js\";\nimport globals from \"globals\";\nimport tseslint from \"typescript-eslint\";\n\nexport default [\n  {\n    files: [\"**/*.{js,mjs,cjs,ts}\"],\n  },\n  { languageOptions: { globals: globals.node } },\n  pluginJs.configs.recommended,\n  ...tseslint.configs.strict,\n  {\n    ignores: [\"*.config.js\", \"coverage/**/**\"],\n  },\n  {\n    languageOptions: {\n      parserOptions: {\n        projectService: {\n          allowDefaultProject: [\n            \"test/project-setups/javascript-*/*.{js,mjs,cjs,ts}\",\n          ],\n        },\n        tsconfigRootDir: import.meta.dirname,\n      },\n    },\n  },\n  {\n    rules: {\n      \"no-unused-vars\": \"off\",\n      \"@typescript-eslint/consistent-type-exports\": \"error\",\n      \"@typescript-eslint/consistent-type-imports\": \"error\",\n      \"@typescript-eslint/no-confusing-void-expression\": \"error\",\n      \"@typescript-eslint/no-duplicate-enum-values\": \"error\",\n      \"@typescript-eslint/no-duplicate-type-constituents\": \"error\",\n      \"@typescript-eslint/no-extraneous-class\": \"error\",\n      \"@typescript-eslint/no-import-type-side-effects\": \"error\",\n      \"@typescript-eslint/no-redundant-type-constituents\": \"error\",\n      \"@typescript-eslint/no-require-imports\": \"error\",\n      \"@typescript-eslint/no-unnecessary-condition\": \"error\",\n      \"@typescript-eslint/no-unnecessary-qualifier\": \"error\",\n      \"@typescript-eslint/no-unused-vars\": \"error\",\n      \"@typescript-eslint/no-useless-empty-export\": \"error\",\n      \"@typescript-eslint/prefer-readonly\": \"error\",\n      \"@typescript-eslint/prefer-regexp-exec\": \"error\",\n      \"@typescript-eslint/require-array-sort-compare\": \"error\",\n      \"@typescript-eslint/switch-exhaustiveness-check\": \"error\",\n    },\n  },\n  {\n    files: [\"test/**/*.{js,mjs,cjs,ts}\"],\n    rules: {\n      \"@typescript-eslint/no-explicit-any\": \"off\",\n      \"@typescript-eslint/no-unsafe-argument\": \"off\",\n      \"@typescript-eslint/no-unsafe-assignment\": \"off\",\n    },\n  },\n  {\n    files: [\"test/project-setups/**/*.{js,mjs,cjs,ts}\"],\n    rules: {\n      \"@typescript-eslint/no-require-imports\": \"off\",\n      \"@typescript-eslint/no-unnecessary-condition\": \"off\",\n    },\n  },\n];\n"
  },
  {
    "path": "index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport contentSecurityPolicy, {\n  type ContentSecurityPolicyOptions,\n} from \"./middlewares/content-security-policy/index.js\";\nimport crossOriginEmbedderPolicy, {\n  type CrossOriginEmbedderPolicyOptions,\n} from \"./middlewares/cross-origin-embedder-policy/index.js\";\nimport crossOriginOpenerPolicy, {\n  type CrossOriginOpenerPolicyOptions,\n} from \"./middlewares/cross-origin-opener-policy/index.js\";\nimport crossOriginResourcePolicy, {\n  type CrossOriginResourcePolicyOptions,\n} from \"./middlewares/cross-origin-resource-policy/index.js\";\nimport originAgentCluster from \"./middlewares/origin-agent-cluster/index.js\";\nimport referrerPolicy, {\n  type ReferrerPolicyOptions,\n} from \"./middlewares/referrer-policy/index.js\";\nimport strictTransportSecurity, {\n  type StrictTransportSecurityOptions,\n} from \"./middlewares/strict-transport-security/index.js\";\nimport xContentTypeOptions from \"./middlewares/x-content-type-options/index.js\";\nimport xDnsPrefetchControl, {\n  type XDnsPrefetchControlOptions,\n} from \"./middlewares/x-dns-prefetch-control/index.js\";\nimport xDownloadOptions from \"./middlewares/x-download-options/index.js\";\nimport xFrameOptions, {\n  type XFrameOptionsOptions,\n} from \"./middlewares/x-frame-options/index.js\";\nimport xPermittedCrossDomainPolicies, {\n  type XPermittedCrossDomainPoliciesOptions,\n} from \"./middlewares/x-permitted-cross-domain-policies/index.js\";\nimport xPoweredBy from \"./middlewares/x-powered-by/index.js\";\nimport xXssProtection from \"./middlewares/x-xss-protection/index.js\";\n\nexport type HelmetOptions = {\n  contentSecurityPolicy?: ContentSecurityPolicyOptions | boolean;\n  crossOriginEmbedderPolicy?: CrossOriginEmbedderPolicyOptions | boolean;\n  crossOriginOpenerPolicy?: CrossOriginOpenerPolicyOptions | boolean;\n  crossOriginResourcePolicy?: CrossOriginResourcePolicyOptions | boolean;\n  originAgentCluster?: boolean;\n  referrerPolicy?: ReferrerPolicyOptions | boolean;\n} & (\n  | {\n      strictTransportSecurity?: StrictTransportSecurityOptions | boolean;\n      hsts?: never;\n    }\n  | {\n      hsts?: StrictTransportSecurityOptions | boolean;\n      strictTransportSecurity?: never;\n    }\n) &\n  (\n    | { xContentTypeOptions?: boolean; noSniff?: never }\n    | { noSniff?: boolean; xContentTypeOptions?: never }\n  ) &\n  (\n    | {\n        xDnsPrefetchControl?: XDnsPrefetchControlOptions | boolean;\n        dnsPrefetchControl?: never;\n      }\n    | {\n        dnsPrefetchControl?: XDnsPrefetchControlOptions | boolean;\n        xDnsPrefetchControl?: never;\n      }\n  ) &\n  (\n    | { xDownloadOptions?: boolean; ieNoOpen?: never }\n    | { ieNoOpen?: boolean; xDownloadOptions?: never }\n  ) &\n  (\n    | { xFrameOptions?: XFrameOptionsOptions | boolean; frameguard?: never }\n    | { frameguard?: XFrameOptionsOptions | boolean; xFrameOptions?: never }\n  ) &\n  (\n    | {\n        xPermittedCrossDomainPolicies?:\n          | XPermittedCrossDomainPoliciesOptions\n          | boolean;\n        permittedCrossDomainPolicies?: never;\n      }\n    | {\n        permittedCrossDomainPolicies?:\n          | XPermittedCrossDomainPoliciesOptions\n          | boolean;\n        xPermittedCrossDomainPolicies?: never;\n      }\n  ) &\n  (\n    | { xPoweredBy?: boolean; hidePoweredBy?: never }\n    | { hidePoweredBy?: boolean; xPoweredBy?: never }\n  ) &\n  (\n    | { xXssProtection?: boolean; xssFilter?: never }\n    | { xssFilter?: boolean; xXssProtection?: never }\n  );\n\ntype MiddlewareFunction = (\n  req: IncomingMessage,\n  res: ServerResponse,\n  next: (error?: Error) => void,\n) => void;\n\ninterface Helmet {\n  (\n    options?: Readonly<HelmetOptions>,\n  ): (\n    req: IncomingMessage,\n    res: ServerResponse,\n    next: (err?: unknown) => void,\n  ) => void;\n\n  contentSecurityPolicy: typeof contentSecurityPolicy;\n  crossOriginEmbedderPolicy: typeof crossOriginEmbedderPolicy;\n  crossOriginOpenerPolicy: typeof crossOriginOpenerPolicy;\n  crossOriginResourcePolicy: typeof crossOriginResourcePolicy;\n  originAgentCluster: typeof originAgentCluster;\n  referrerPolicy: typeof referrerPolicy;\n  strictTransportSecurity: typeof strictTransportSecurity;\n  xContentTypeOptions: typeof xContentTypeOptions;\n  xDnsPrefetchControl: typeof xDnsPrefetchControl;\n  xDownloadOptions: typeof xDownloadOptions;\n  xFrameOptions: typeof xFrameOptions;\n  xPermittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies;\n  xPoweredBy: typeof xPoweredBy;\n  xXssProtection: typeof xXssProtection;\n\n  // Legacy aliases\n  dnsPrefetchControl: typeof xDnsPrefetchControl;\n  frameguard: typeof xFrameOptions;\n  hidePoweredBy: typeof xPoweredBy;\n  hsts: typeof strictTransportSecurity;\n  ieNoOpen: typeof xDownloadOptions;\n  noSniff: typeof xContentTypeOptions;\n  permittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies;\n  xssFilter: typeof xXssProtection;\n}\n\nfunction getMiddlewareFunctionsFromOptions(\n  options: Readonly<HelmetOptions>,\n): MiddlewareFunction[] {\n  const result: MiddlewareFunction[] = [];\n\n  switch (options.contentSecurityPolicy) {\n    case undefined:\n    case true:\n      result.push(contentSecurityPolicy());\n      break;\n    case false:\n      break;\n    default:\n      result.push(contentSecurityPolicy(options.contentSecurityPolicy));\n      break;\n  }\n\n  switch (options.crossOriginEmbedderPolicy) {\n    case undefined:\n    case false:\n      break;\n    case true:\n      result.push(crossOriginEmbedderPolicy());\n      break;\n    default:\n      result.push(crossOriginEmbedderPolicy(options.crossOriginEmbedderPolicy));\n      break;\n  }\n\n  switch (options.crossOriginOpenerPolicy) {\n    case undefined:\n    case true:\n      result.push(crossOriginOpenerPolicy());\n      break;\n    case false:\n      break;\n    default:\n      result.push(crossOriginOpenerPolicy(options.crossOriginOpenerPolicy));\n      break;\n  }\n\n  switch (options.crossOriginResourcePolicy) {\n    case undefined:\n    case true:\n      result.push(crossOriginResourcePolicy());\n      break;\n    case false:\n      break;\n    default:\n      result.push(crossOriginResourcePolicy(options.crossOriginResourcePolicy));\n      break;\n  }\n\n  switch (options.originAgentCluster) {\n    case undefined:\n    case true:\n      result.push(originAgentCluster());\n      break;\n    case false:\n      break;\n    default:\n      console.warn(\n        \"Origin-Agent-Cluster does not take options. Remove the property to silence this warning.\",\n      );\n      result.push(originAgentCluster());\n      break;\n  }\n\n  switch (options.referrerPolicy) {\n    case undefined:\n    case true:\n      result.push(referrerPolicy());\n      break;\n    case false:\n      break;\n    default:\n      result.push(referrerPolicy(options.referrerPolicy));\n      break;\n  }\n\n  if (\"strictTransportSecurity\" in options && \"hsts\" in options) {\n    throw new Error(\n      \"Strict-Transport-Security option was specified twice. Remove the `hsts` option to fix this error.\",\n    );\n  }\n  const strictTransportSecurityOption =\n    options.strictTransportSecurity ?? options.hsts;\n  switch (strictTransportSecurityOption) {\n    case undefined:\n    case true:\n      result.push(strictTransportSecurity());\n      break;\n    case false:\n      break;\n    default:\n      result.push(strictTransportSecurity(strictTransportSecurityOption));\n      break;\n  }\n\n  if (\"xContentTypeOptions\" in options && \"noSniff\" in options) {\n    throw new Error(\n      \"X-Content-Type-Options option was specified twice. Remove the `noSniff` option to fix this error.\",\n    );\n  }\n  const xContentTypeOptionsOption =\n    options.xContentTypeOptions ?? options.noSniff;\n  switch (xContentTypeOptionsOption) {\n    case undefined:\n    case true:\n      result.push(xContentTypeOptions());\n      break;\n    case false:\n      break;\n    default:\n      console.warn(\n        \"X-Content-Type-Options does not take options. Remove the property to silence this warning.\",\n      );\n      result.push(xContentTypeOptions());\n      break;\n  }\n\n  if (\"xDnsPrefetchControl\" in options && \"dnsPrefetchControl\" in options) {\n    throw new Error(\n      \"X-DNS-Prefetch-Control option was specified twice. Remove the `dnsPrefetchControl` option to fix this error.\",\n    );\n  }\n  const xDnsPrefetchControlOption =\n    options.xDnsPrefetchControl ?? options.dnsPrefetchControl;\n  switch (xDnsPrefetchControlOption) {\n    case undefined:\n    case true:\n      result.push(xDnsPrefetchControl());\n      break;\n    case false:\n      break;\n    default:\n      result.push(xDnsPrefetchControl(xDnsPrefetchControlOption));\n      break;\n  }\n\n  if (\"xDownloadOptions\" in options && \"ieNoOpen\" in options) {\n    throw new Error(\n      \"X-Download-Options option was specified twice. Remove the `ieNoOpen` option to fix this error.\",\n    );\n  }\n  const xDownloadOptionsOption = options.xDownloadOptions ?? options.ieNoOpen;\n  switch (xDownloadOptionsOption) {\n    case undefined:\n    case true:\n      result.push(xDownloadOptions());\n      break;\n    case false:\n      break;\n    default:\n      console.warn(\n        \"X-Download-Options does not take options. Remove the property to silence this warning.\",\n      );\n      result.push(xDownloadOptions());\n      break;\n  }\n\n  if (\"xFrameOptions\" in options && \"frameguard\" in options) {\n    throw new Error(\n      \"X-Frame-Options option was specified twice. Remove the `frameguard` option to fix this error.\",\n    );\n  }\n  const xFrameOptionsOption = options.xFrameOptions ?? options.frameguard;\n  switch (xFrameOptionsOption) {\n    case undefined:\n    case true:\n      result.push(xFrameOptions());\n      break;\n    case false:\n      break;\n    default:\n      result.push(xFrameOptions(xFrameOptionsOption));\n      break;\n  }\n\n  if (\n    \"xPermittedCrossDomainPolicies\" in options &&\n    \"permittedCrossDomainPolicies\" in options\n  ) {\n    throw new Error(\n      \"X-Permitted-Cross-Domain-Policies option was specified twice. Remove the `permittedCrossDomainPolicies` option to fix this error.\",\n    );\n  }\n  const xPermittedCrossDomainPoliciesOption =\n    options.xPermittedCrossDomainPolicies ??\n    options.permittedCrossDomainPolicies;\n  switch (xPermittedCrossDomainPoliciesOption) {\n    case undefined:\n    case true:\n      result.push(xPermittedCrossDomainPolicies());\n      break;\n    case false:\n      break;\n    default:\n      result.push(\n        xPermittedCrossDomainPolicies(xPermittedCrossDomainPoliciesOption),\n      );\n      break;\n  }\n\n  if (\"xPoweredBy\" in options && \"hidePoweredBy\" in options) {\n    throw new Error(\n      \"X-Powered-By option was specified twice. Remove the `hidePoweredBy` option to fix this error.\",\n    );\n  }\n  const xPoweredByOption = options.xPoweredBy ?? options.hidePoweredBy;\n  switch (xPoweredByOption) {\n    case undefined:\n    case true:\n      result.push(xPoweredBy());\n      break;\n    case false:\n      break;\n    default:\n      console.warn(\n        \"X-Powered-By does not take options. Remove the property to silence this warning.\",\n      );\n      result.push(xPoweredBy());\n      break;\n  }\n\n  if (\"xXssProtection\" in options && \"xssFilter\" in options) {\n    throw new Error(\n      \"X-XSS-Protection option was specified twice. Remove the `xssFilter` option to fix this error.\",\n    );\n  }\n  const xXssProtectionOption = options.xXssProtection ?? options.xssFilter;\n  switch (xXssProtectionOption) {\n    case undefined:\n    case true:\n      result.push(xXssProtection());\n      break;\n    case false:\n      break;\n    default:\n      console.warn(\n        \"X-XSS-Protection does not take options. Remove the property to silence this warning.\",\n      );\n      result.push(xXssProtection());\n      break;\n  }\n\n  return result;\n}\n\nconst helmet: Helmet = Object.assign(\n  function helmet(options: Readonly<HelmetOptions> = {}) {\n    // People should be able to pass an options object with no prototype,\n    // so we want this optional chaining.\n    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n    if (options.constructor?.name === \"IncomingMessage\") {\n      throw new Error(\n        \"It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.\",\n      );\n    }\n\n    const middlewareFunctions = getMiddlewareFunctionsFromOptions(options);\n\n    return function helmetMiddleware(\n      req: IncomingMessage,\n      res: ServerResponse,\n      next: (err?: unknown) => void,\n    ): void {\n      let middlewareIndex = 0;\n\n      (function internalNext(err?: unknown) {\n        if (err) {\n          next(err);\n          return;\n        }\n\n        const middlewareFunction = middlewareFunctions[middlewareIndex];\n        if (middlewareFunction) {\n          middlewareIndex++;\n          middlewareFunction(req, res, internalNext);\n        } else {\n          next();\n        }\n      })();\n    };\n  },\n  {\n    contentSecurityPolicy,\n    crossOriginEmbedderPolicy,\n    crossOriginOpenerPolicy,\n    crossOriginResourcePolicy,\n    originAgentCluster,\n    referrerPolicy,\n    strictTransportSecurity,\n    xContentTypeOptions,\n    xDnsPrefetchControl,\n    xDownloadOptions,\n    xFrameOptions,\n    xPermittedCrossDomainPolicies,\n    xPoweredBy,\n    xXssProtection,\n\n    // Legacy aliases\n    dnsPrefetchControl: xDnsPrefetchControl,\n    xssFilter: xXssProtection,\n    permittedCrossDomainPolicies: xPermittedCrossDomainPolicies,\n    ieNoOpen: xDownloadOptions,\n    noSniff: xContentTypeOptions,\n    frameguard: xFrameOptions,\n    hidePoweredBy: xPoweredBy,\n    hsts: strictTransportSecurity,\n  },\n);\n\nexport default helmet;\n\nexport {\n  contentSecurityPolicy,\n  crossOriginEmbedderPolicy,\n  crossOriginOpenerPolicy,\n  crossOriginResourcePolicy,\n  originAgentCluster,\n  referrerPolicy,\n  strictTransportSecurity,\n  xContentTypeOptions,\n  xDnsPrefetchControl,\n  xDownloadOptions,\n  xFrameOptions,\n  xPoweredBy,\n  xXssProtection,\n\n  // Legacy aliases\n  strictTransportSecurity as hsts,\n  xContentTypeOptions as noSniff,\n  xDnsPrefetchControl as dnsPrefetchControl,\n  xDownloadOptions as ieNoOpen,\n  xFrameOptions as frameguard,\n  xPermittedCrossDomainPolicies,\n  xPermittedCrossDomainPolicies as permittedCrossDomainPolicies,\n  xPoweredBy as hidePoweredBy,\n  xXssProtection as xssFilter,\n};\n"
  },
  {
    "path": "middlewares/content-security-policy/CHANGELOG.md",
    "content": "# Changelog\n\n## 4.0.0 - 2024-06-01\n\n### Changed\n\n- **Breaking:** `useDefaults` option now defaults to `true`\n- **Breaking:** `form-action` directive is now set to `'self'` by default\n- **Breaking:** `block-all-mixed-content` is no longer set by default\n\n### Removed\n\n- **Breaking:** Node 18+ is now required\n\n## 3.4.0 - 2021-05-02\n\n### Added\n\n- New `useDefaults` option, defaulting to `false`, lets you selectively override defaults more easily\n\n## 3.3.1 - 2020-12-27\n\n### Fixed\n\n- Broken TypeScript types. See [#283](https://github.com/helmetjs/helmet/issues/283)\n\n## 3.3.0 - 2020-12-27\n\n### Added\n\n- Setting the `default-src` to `contentSecurityPolicy.dangerouslyDisableDefaultSrc` disables it\n\n## 3.2.0 - 2020-11-01\n\n### Added\n\n- Get the default directives with `contentSecurityPolicy.getDefaultDirectives()`\n\n## 3.1.0 - 2020-08-15\n\n### Added\n\n- Directive values can now include functions, as they could in Helmet 3. See [#243](https://github.com/helmetjs/helmet/issues/243)\n\n## 3.0.0 - 2020-08-02\n\n### Added\n\n- If no `default-src` directive is supplied, an error is thrown\n- Directive lists can be any iterable, not just arrays\n\n### Changed\n\n- There is now a default set of directives if none are supplied\n- Duplicate keys now throw an error. See [helmetjs/csp#73](https://github.com/helmetjs/csp/issues/73)\n- This middleware is more lenient, allowing more directive names or values\n\n### Removed\n\n- Removed browser sniffing (including the `browserSniff` parameter). See [#97](https://github.com/helmetjs/csp/issues/97)\n- Removed conditional support. This includes directive functions and support for a function as the `reportOnly`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware)\n- Removed a lot of checks—you should be checking your CSP with a different tool\n- Removed support for legacy headers (and therefore the `setAllHeaders` parameter). [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Setting-legacy-Content-Security-Policy-headers-in-Helmet-4)\n- Dropped support for old Node versions. Node 10+ is now required\n- Removed the `loose` option\n- Removed support for functions as directive values. You must supply an iterable of strings\n- Removed the `disableAndroid` option\n\n## 2.9.5 - 2020-02-22\n\n### Changed\n\n- Updated `bowser` subdependency from 2.7.0 to 2.9.0\n\n### Fixed\n\n- Fixed an issue some people were having when importing the `bowser` subdependency. See [#96](https://github.com/helmetjs/csp/issues/96) and [#101](https://github.com/helmetjs/csp/pull/101)\n- Fixed a link in the readme. See [#100](https://github.com/helmetjs/csp/pull/100)\n\n## 2.9.4 - 2019-10-21\n\n### Changed\n\n- Updated `bowser` subdependency from 2.6.1 to 2.7.0. See [#94](https://github.com/helmetjs/csp/pull/94)\n\n## 2.9.3 - 2019-09-30\n\n### Fixed\n\n- Published a missing TypeScript type definition file. See [#90](https://github.com/helmetjs/csp/issues/90)\n\n## 2.9.2 - 2019-09-20\n\n### Fixed\n\n- Fixed a bug where a request from Firefox 4 could delete `default-src` from future responses\n- Fixed tablet PC detection by updating `bowser` subdependency to latest version\n\n## 2.9.1 - 2019-09-04\n\n### Changed\n\n- Updated `bowser` subdependency from 2.5.3 to 2.5.4. See [#88](https://github.com/helmetjs/csp/pull/88)\n\n### Fixed\n\n- The \"security\" keyword was declared twice in package metadata. See [#87](https://github.com/helmetjs/csp/pull/87)\n\n## 2.9.0 - 2019-08-28\n\n### Added\n\n- Added TypeScript type definitions. See [#86](https://github.com/helmetjs/csp/pull/86)\n\n### Fixed\n\n- Switched from `platform` to `bowser` to quiet a security vulnerability warning. See [#80](https://github.com/helmetjs/csp/issues/80)\n\n## 2.8.0 - 2019-07-24\n\n### Added\n\n- Added a new `sandbox` directive, `allow-downloads-without-user-activation` (see [#85](https://github.com/helmetjs/csp/pull/85))\n- Created a changelog\n- Added some package metadata\n\n### Changed\n\n- Updated documentation to use ES2015\n- Updated documentation to remove dependency on UUID package\n- Updated `content-security-policy-builder` to 2.1.0\n- Excluded some files from the npm package\n\nChanges in versions 2.7.1 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/content-security-policy/README.md",
    "content": "# Content Security Policy middleware\n\nThe `Content-Security-Policy` header mitigates a large number of attacks, such as [cross-site scripting][XSS]. See [MDN's introductory article on Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).\n\nThis header is powerful but likely requires some configuration for your specific app.\n\nTo configure this header, pass an object with a nested `directives` object. Each key is a directive name in camel case (such as `defaultSrc`) or kebab case (such as `default-src`). Each value is an array (or other iterable) of strings or functions for that directive. If a function appears in the array, it will be called with the request and response objects.\n\n```javascript\nconst contentSecurityPolicy = require(\"helmet-csp\");\n\n// Sets all of the defaults, but overrides `script-src`\n// and disables the default `style-src`.\napp.use(\n  contentSecurityPolicy({\n    directives: {\n      \"script-src\": [\"'self'\", \"example.com\"],\n      \"style-src\": null,\n    },\n  }),\n);\n```\n\n```js\n// Sets the `script-src` directive to\n// \"'self' 'nonce-e33cc...'\"\n// (or similar)\napp.use((req, res, next) => {\n  res.locals.cspNonce = crypto.randomBytes(32).toString(\"hex\");\n  next();\n});\napp.use(\n  contentSecurityPolicy({\n    directives: {\n      scriptSrc: [\"'self'\", (req, res) => `'nonce-${res.locals.cspNonce}'`],\n    },\n  }),\n);\n```\n\nThese directives are merged into a default policy, which you can disable by setting `useDefaults` to `false`.\n\n```javascript\n// Sets \"Content-Security-Policy: default-src 'self';\n// script-src 'self' example.com;object-src 'none';\n// upgrade-insecure-requests\"\napp.use(\n  contentSecurityPolicy({\n    useDefaults: false,\n    directives: {\n      defaultSrc: [\"'self'\"],\n      scriptSrc: [\"'self'\", \"example.com\"],\n      objectSrc: [\"'none'\"],\n      upgradeInsecureRequests: [],\n    },\n  }),\n);\n```\n\nYou can get the default directives object with `contentSecurityPolicy.getDefaultDirectives()`. Here is the default policy (formatted for readability):\n\n```\ndefault-src 'self';\nbase-uri 'self';\nfont-src 'self' https: data:;\nform-action 'self';\nframe-ancestors 'self';\nimg-src 'self' data:;\nobject-src 'none';\nscript-src 'self';\nscript-src-attr 'none';\nstyle-src 'self' https: 'unsafe-inline';\nupgrade-insecure-requests\n```\n\nThe `default-src` directive can be explicitly disabled by setting its value to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`, but this is not recommended.\n\nYou can set the [`Content-Security-Policy-Report-Only`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only) instead:\n\n```javascript\n// Sets the Content-Security-Policy-Report-Only header\napp.use(\n  contentSecurityPolicy({\n    directives: {\n      /* ... */\n    },\n    reportOnly: true,\n  }),\n);\n```\n\n`upgrade-insecure-requests`, a directive that causes browsers to upgrade HTTP to HTTPS, is set by default. You may wish to avoid this in development, as you may not be developing with HTTPS. Notably, Safari will upgrade `http://localhost` to `https://localhost`, which can cause problems. To work around this, you may wish to disable the `upgrade-insecure-requests` directive in development. For example:\n\n```js\nconst isDevelopment = app.get(\"env\") === \"development\";\n\napp.use(\n  contentSecurityPolicy({\n    directives: {\n      // Disable upgrade-insecure-requests in development.\n      \"upgrade-insecure-requests\": isDevelopment ? null : [],\n    },\n  }),\n);\n```\n\nThis module performs very little validation on your CSP. You should rely on CSP checkers like [CSP Evaluator](https://csp-evaluator.withgoogle.com/) instead.\n"
  },
  {
    "path": "middlewares/content-security-policy/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\ntype ContentSecurityPolicyDirectiveValueFunction = (\n  req: IncomingMessage,\n  res: ServerResponse,\n) => string;\n\ntype ContentSecurityPolicyDirectiveValue =\n  | string\n  | ContentSecurityPolicyDirectiveValueFunction;\n\nexport interface ContentSecurityPolicyOptions {\n  useDefaults?: boolean;\n  directives?: Record<\n    string,\n    | null\n    | Iterable<ContentSecurityPolicyDirectiveValue>\n    | typeof dangerouslyDisableDefaultSrc\n  >;\n  reportOnly?: boolean;\n}\n\ntype NormalizedDirectives = Map<\n  string,\n  Iterable<ContentSecurityPolicyDirectiveValue>\n>;\n\ninterface ContentSecurityPolicy {\n  (\n    options?: Readonly<ContentSecurityPolicyOptions>,\n  ): (\n    req: IncomingMessage,\n    res: ServerResponse,\n    next: (err?: Error) => void,\n  ) => void;\n  getDefaultDirectives: typeof getDefaultDirectives;\n  dangerouslyDisableDefaultSrc: typeof dangerouslyDisableDefaultSrc;\n}\n\nconst dangerouslyDisableDefaultSrc = Symbol(\"dangerouslyDisableDefaultSrc\");\n\nconst SHOULD_BE_QUOTED: ReadonlySet<string> = new Set([\n  \"none\",\n  \"self\",\n  \"strict-dynamic\",\n  \"report-sample\",\n  \"inline-speculation-rules\",\n  \"unsafe-inline\",\n  \"unsafe-eval\",\n  \"unsafe-hashes\",\n  \"wasm-unsafe-eval\",\n]);\n\nconst getDefaultDirectives = (): Record<\n  string,\n  Iterable<ContentSecurityPolicyDirectiveValue>\n> => ({\n  \"default-src\": [\"'self'\"],\n  \"base-uri\": [\"'self'\"],\n  \"font-src\": [\"'self'\", \"https:\", \"data:\"],\n  \"form-action\": [\"'self'\"],\n  \"frame-ancestors\": [\"'self'\"],\n  \"img-src\": [\"'self'\", \"data:\"],\n  \"object-src\": [\"'none'\"],\n  \"script-src\": [\"'self'\"],\n  \"script-src-attr\": [\"'none'\"],\n  \"style-src\": [\"'self'\", \"https:\", \"'unsafe-inline'\"],\n  \"upgrade-insecure-requests\": [],\n});\n\nconst dashify = (str: string): string =>\n  str.replace(/[A-Z]/g, (capitalLetter) => \"-\" + capitalLetter.toLowerCase());\n\nconst assertDirectiveValueIsValid = (\n  directiveName: string,\n  directiveValue: string,\n): void => {\n  if (/;|,/.test(directiveValue)) {\n    throw new Error(\n      `Content-Security-Policy received an invalid directive value for ${JSON.stringify(\n        directiveName,\n      )}`,\n    );\n  }\n};\n\nconst assertDirectiveValueEntryIsValid = (\n  directiveName: string,\n  directiveValueEntry: string,\n): void => {\n  if (\n    SHOULD_BE_QUOTED.has(directiveValueEntry) ||\n    directiveValueEntry.startsWith(\"nonce-\") ||\n    directiveValueEntry.startsWith(\"sha256-\") ||\n    directiveValueEntry.startsWith(\"sha384-\") ||\n    directiveValueEntry.startsWith(\"sha512-\")\n  ) {\n    throw new Error(\n      `Content-Security-Policy received an invalid directive value for ${JSON.stringify(\n        directiveName,\n      )}. ${JSON.stringify(directiveValueEntry)} should be quoted`,\n    );\n  }\n};\n\nfunction normalizeDirectives(\n  options: Readonly<ContentSecurityPolicyOptions>,\n): NormalizedDirectives {\n  const defaultDirectives = getDefaultDirectives();\n\n  const { useDefaults = true, directives: rawDirectives = defaultDirectives } =\n    options;\n\n  const result: NormalizedDirectives = new Map();\n  const directiveNamesSeen = new Set<string>();\n  const directivesExplicitlyDisabled = new Set<string>();\n\n  for (const rawDirectiveName in rawDirectives) {\n    if (!Object.hasOwn(rawDirectives, rawDirectiveName)) {\n      continue;\n    }\n\n    if (\n      rawDirectiveName.length === 0 ||\n      /[^a-zA-Z0-9-]/.test(rawDirectiveName)\n    ) {\n      throw new Error(\n        `Content-Security-Policy received an invalid directive name ${JSON.stringify(\n          rawDirectiveName,\n        )}`,\n      );\n    }\n\n    const directiveName = dashify(rawDirectiveName);\n\n    if (directiveNamesSeen.has(directiveName)) {\n      throw new Error(\n        `Content-Security-Policy received a duplicate directive ${JSON.stringify(\n          directiveName,\n        )}`,\n      );\n    }\n    directiveNamesSeen.add(directiveName);\n\n    const rawDirectiveValue = rawDirectives[rawDirectiveName];\n    let directiveValue: Iterable<ContentSecurityPolicyDirectiveValue>;\n    if (rawDirectiveValue === null) {\n      if (directiveName === \"default-src\") {\n        throw new Error(\n          \"Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.\",\n        );\n      }\n      directivesExplicitlyDisabled.add(directiveName);\n      continue;\n    } else if (typeof rawDirectiveValue === \"string\") {\n      directiveValue = [rawDirectiveValue];\n    } else if (!rawDirectiveValue) {\n      throw new Error(\n        `Content-Security-Policy received an invalid directive value for ${JSON.stringify(\n          directiveName,\n        )}`,\n      );\n    } else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) {\n      if (directiveName === \"default-src\") {\n        directivesExplicitlyDisabled.add(\"default-src\");\n        continue;\n      } else {\n        throw new Error(\n          `Content-Security-Policy: tried to disable ${JSON.stringify(\n            directiveName,\n          )} as if it were default-src; simply omit the key`,\n        );\n      }\n    } else {\n      directiveValue = rawDirectiveValue;\n    }\n\n    for (const element of directiveValue) {\n      if (typeof element !== \"string\") continue;\n      assertDirectiveValueIsValid(directiveName, element);\n      assertDirectiveValueEntryIsValid(directiveName, element);\n    }\n\n    result.set(directiveName, directiveValue);\n  }\n\n  if (useDefaults) {\n    Object.entries(defaultDirectives).forEach(\n      ([defaultDirectiveName, defaultDirectiveValue]) => {\n        if (\n          !result.has(defaultDirectiveName) &&\n          !directivesExplicitlyDisabled.has(defaultDirectiveName)\n        ) {\n          result.set(defaultDirectiveName, defaultDirectiveValue);\n        }\n      },\n    );\n  }\n\n  if (!result.size) {\n    throw new Error(\n      \"Content-Security-Policy has no directives. Either set some or disable the header\",\n    );\n  }\n  if (\n    !result.has(\"default-src\") &&\n    !directivesExplicitlyDisabled.has(\"default-src\")\n  ) {\n    throw new Error(\n      \"Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.\",\n    );\n  }\n\n  return result;\n}\n\nfunction getHeaderValue(\n  req: IncomingMessage,\n  res: ServerResponse,\n  normalizedDirectives: Readonly<NormalizedDirectives>,\n): string | Error {\n  const result: string[] = [];\n\n  for (const [directiveName, rawDirectiveValue] of normalizedDirectives) {\n    let directiveValue = \"\";\n    for (const element of rawDirectiveValue) {\n      if (typeof element === \"function\") {\n        const newElement = element(req, res);\n        assertDirectiveValueEntryIsValid(directiveName, newElement);\n        directiveValue += \" \" + newElement;\n      } else {\n        directiveValue += \" \" + element;\n      }\n    }\n\n    if (directiveValue) {\n      assertDirectiveValueIsValid(directiveName, directiveValue);\n      result.push(`${directiveName}${directiveValue}`);\n    } else {\n      result.push(directiveName);\n    }\n  }\n\n  return result.join(\";\");\n}\n\nconst contentSecurityPolicy: ContentSecurityPolicy =\n  function contentSecurityPolicy(\n    options: Readonly<ContentSecurityPolicyOptions> = {},\n  ): (\n    req: IncomingMessage,\n    res: ServerResponse,\n    next: (err?: Error) => void,\n  ) => void {\n    const headerName = options.reportOnly\n      ? \"Content-Security-Policy-Report-Only\"\n      : \"Content-Security-Policy\";\n\n    const normalizedDirectives = normalizeDirectives(options);\n\n    return function contentSecurityPolicyMiddleware(\n      req: IncomingMessage,\n      res: ServerResponse,\n      next: (error?: Error) => void,\n    ) {\n      const result = getHeaderValue(req, res, normalizedDirectives);\n      if (result instanceof Error) {\n        next(result);\n      } else {\n        res.setHeader(headerName, result);\n        next();\n      }\n    };\n  };\ncontentSecurityPolicy.getDefaultDirectives = getDefaultDirectives;\ncontentSecurityPolicy.dangerouslyDisableDefaultSrc =\n  dangerouslyDisableDefaultSrc;\n\nexport default contentSecurityPolicy;\n\nexport { dangerouslyDisableDefaultSrc, getDefaultDirectives };\n"
  },
  {
    "path": "middlewares/content-security-policy/package-overrides.json",
    "content": "{\n  \"name\": \"helmet-csp\",\n  \"author\": \"Adam Baldwin <adam@npmjs.com> (https://evilpacket.net)\",\n  \"contributors\": [\n    \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n    \"Ryan Cannon <ryan@ryancannon.com> (https://ryancannon.com)\"\n  ],\n  \"description\": \"Content Security Policy middleware\",\n  \"version\": \"4.0.0\",\n  \"keywords\": [\"express\", \"security\", \"content-security-policy\", \"csp\", \"xss\"],\n  \"engines\": {\n    \"node\": \">=18.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/cross-origin-embedder-policy/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport interface CrossOriginEmbedderPolicyOptions {\n  policy?: \"require-corp\" | \"credentialless\" | \"unsafe-none\";\n}\n\nconst ALLOWED_POLICIES = new Set([\n  \"require-corp\",\n  \"credentialless\",\n  \"unsafe-none\",\n]);\n\nfunction getHeaderValueFromOptions({\n  policy = \"require-corp\",\n}: Readonly<CrossOriginEmbedderPolicyOptions>): string {\n  if (ALLOWED_POLICIES.has(policy)) {\n    return policy;\n  } else {\n    throw new Error(\n      `Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(\n        policy,\n      )} policy`,\n    );\n  }\n}\n\nfunction crossOriginEmbedderPolicy(\n  options: Readonly<CrossOriginEmbedderPolicyOptions> = {},\n) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function crossOriginEmbedderPolicyMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"Cross-Origin-Embedder-Policy\", headerValue);\n    next();\n  };\n}\n\nexport default crossOriginEmbedderPolicy;\n"
  },
  {
    "path": "middlewares/cross-origin-opener-policy/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport interface CrossOriginOpenerPolicyOptions {\n  policy?:\n    | \"same-origin\"\n    | \"same-origin-allow-popups\"\n    | \"noopener-allow-popups\"\n    | \"unsafe-none\";\n}\n\nconst ALLOWED_POLICIES = new Set([\n  \"same-origin\",\n  \"same-origin-allow-popups\",\n  \"noopener-allow-popups\",\n  \"unsafe-none\",\n]);\n\nfunction getHeaderValueFromOptions({\n  policy = \"same-origin\",\n}: Readonly<CrossOriginOpenerPolicyOptions>): string {\n  if (ALLOWED_POLICIES.has(policy)) {\n    return policy;\n  } else {\n    throw new Error(\n      `Cross-Origin-Opener-Policy does not support the ${JSON.stringify(\n        policy,\n      )} policy`,\n    );\n  }\n}\n\nfunction crossOriginOpenerPolicy(\n  options: Readonly<CrossOriginOpenerPolicyOptions> = {},\n) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function crossOriginOpenerPolicyMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"Cross-Origin-Opener-Policy\", headerValue);\n    next();\n  };\n}\n\nexport default crossOriginOpenerPolicy;\n"
  },
  {
    "path": "middlewares/cross-origin-resource-policy/CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n### Changed\n\n- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)\n\n## 0.3.0 - 2021-04-17\n\n### Added\n\n- Added support for the `cross-origin` policy\n\n## 0.2.1 - 2020-12-22\n\n### Fixed\n\n- Fixed incorrect example in README\n\n## 0.2.0 - 2019-07-17\n\n### Added\n\n- Added TypeScript type definitions. See [#2](https://github.com/helmetjs/cross-origin-resource-policy/pull/2) and [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n- Added some additional package metadata: homepage, email for bug reports, and a list of supported Node versions\n\n### Changed\n\n- Excluded some files from npm package\n\nThis changelog was started in version 0.2.0.\n"
  },
  {
    "path": "middlewares/cross-origin-resource-policy/README.md",
    "content": "# Cross-Origin-Resource-Policy middleware\n\nThis middleware sets the `Cross-Origin-Resource-Policy` header. Read about it [in the spec](https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header).\n\nUsage:\n\n```javascript\nconst crossOriginResourcePolicy = require(\"cross-origin-resource-policy\");\n\n// Sets \"Cross-Origin-Resource-Policy: same-origin\"\napp.use(crossOriginResourcePolicy({ policy: \"same-origin\" }));\n\n// Sets \"Cross-Origin-Resource-Policy: same-site\"\napp.use(crossOriginResourcePolicy({ policy: \"same-site\" }));\n```\n"
  },
  {
    "path": "middlewares/cross-origin-resource-policy/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport interface CrossOriginResourcePolicyOptions {\n  policy?: \"same-origin\" | \"same-site\" | \"cross-origin\";\n}\n\nconst ALLOWED_POLICIES = new Set([\"same-origin\", \"same-site\", \"cross-origin\"]);\n\nfunction getHeaderValueFromOptions({\n  policy = \"same-origin\",\n}: Readonly<CrossOriginResourcePolicyOptions>): string {\n  if (ALLOWED_POLICIES.has(policy)) {\n    return policy;\n  } else {\n    throw new Error(\n      `Cross-Origin-Resource-Policy does not support the ${JSON.stringify(\n        policy,\n      )} policy`,\n    );\n  }\n}\n\nfunction crossOriginResourcePolicy(\n  options: Readonly<CrossOriginResourcePolicyOptions> = {},\n) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function crossOriginResourcePolicyMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"Cross-Origin-Resource-Policy\", headerValue);\n    next();\n  };\n}\n\nexport default crossOriginResourcePolicy;\n"
  },
  {
    "path": "middlewares/cross-origin-resource-policy/package-overrides.json",
    "content": "{\n  \"name\": \"cross-origin-resource-policy\",\n  \"author\": \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n  \"contributors\": [],\n  \"description\": \"Middleware to set the Cross-Origin-Resource-Policy header\",\n  \"version\": \"0.3.0\",\n  \"keywords\": [\"cross-origin-resource-policy\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/origin-agent-cluster/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nfunction originAgentCluster() {\n  return function originAgentClusterMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ): void {\n    res.setHeader(\"Origin-Agent-Cluster\", \"?1\");\n    next();\n  };\n}\n\nexport default originAgentCluster;\n"
  },
  {
    "path": "middlewares/referrer-policy/CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n### Changed\n\n- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)\n\n## 2.0.0 - Unreleased\n\n### Removed\n\n- **Breaking:** Dropped support for old Node versions. Node 10+ is now required\n\n## 1.2.0 - 2019-05-03\n\n### Added\n\n- Allow multiple values to be set. See [#7](https://github.com/helmetjs/referrer-policy/issues/7)\n- Added TypeScript type definitions. See [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n\n### Changed\n\n- Updated documentation\n\nChanges in versions 1.1.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/referrer-policy/README.md",
    "content": "# Referrer-Policy middleware\n\nThe [Referer HTTP header](https://en.wikipedia.org/wiki/HTTP_referer) is typically set by web browsers to tell the server where it's coming from. For example, if you click a link on _example.com/index.html_ that takes you to _wikipedia.org_, Wikipedia's servers will see `Referer: example.com`. This can have privacy implications—websites can see where you are coming from. The new [`Referrer-Policy` HTTP header](https://www.w3.org/TR/referrer-policy/#referrer-policy-header) lets authors control how browsers set the Referer header.\n\n[Read the spec](https://www.w3.org/TR/referrer-policy/#referrer-policies) to see the options you can provide.\n\nUsage:\n\n```javascript\nconst referrerPolicy = require(\"referrer-policy\");\n\napp.use(referrerPolicy({ policy: \"same-origin\" }));\n// Referrer-Policy: same-origin\n\napp.use(referrerPolicy({ policy: \"unsafe-url\" }));\n// Referrer-Policy: unsafe-url\n\napp.use(\n  referrerPolicy({\n    policy: [\"no-referrer\", \"unsafe-url\"],\n  }),\n);\n// Referrer-Policy: no-referrer,unsafe-url\n\napp.use(referrerPolicy());\n// Referrer-Policy: no-referrer\n```\n"
  },
  {
    "path": "middlewares/referrer-policy/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\ntype ReferrerPolicyToken =\n  | \"no-referrer\"\n  | \"no-referrer-when-downgrade\"\n  | \"same-origin\"\n  | \"origin\"\n  | \"strict-origin\"\n  | \"origin-when-cross-origin\"\n  | \"strict-origin-when-cross-origin\"\n  | \"unsafe-url\"\n  | \"\";\n\nexport interface ReferrerPolicyOptions {\n  policy?: ReferrerPolicyToken | ReferrerPolicyToken[];\n}\n\nconst ALLOWED_TOKENS = new Set<ReferrerPolicyToken>([\n  \"no-referrer\",\n  \"no-referrer-when-downgrade\",\n  \"same-origin\",\n  \"origin\",\n  \"strict-origin\",\n  \"origin-when-cross-origin\",\n  \"strict-origin-when-cross-origin\",\n  \"unsafe-url\",\n  \"\",\n]);\n\nfunction getHeaderValueFromOptions({\n  policy = [\"no-referrer\"],\n}: Readonly<ReferrerPolicyOptions>): string {\n  const tokens = typeof policy === \"string\" ? [policy] : policy;\n\n  if (tokens.length === 0) {\n    throw new Error(\"Referrer-Policy received no policy tokens\");\n  }\n\n  const tokensSeen = new Set<ReferrerPolicyToken>();\n  tokens.forEach((token) => {\n    if (!ALLOWED_TOKENS.has(token)) {\n      throw new Error(\n        `Referrer-Policy received an unexpected policy token ${JSON.stringify(\n          token,\n        )}`,\n      );\n    } else if (tokensSeen.has(token)) {\n      throw new Error(\n        `Referrer-Policy received a duplicate policy token ${JSON.stringify(\n          token,\n        )}`,\n      );\n    }\n    tokensSeen.add(token);\n  });\n\n  return tokens.join(\",\");\n}\n\nfunction referrerPolicy(options: Readonly<ReferrerPolicyOptions> = {}) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function referrerPolicyMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"Referrer-Policy\", headerValue);\n    next();\n  };\n}\n\nexport default referrerPolicy;\n"
  },
  {
    "path": "middlewares/referrer-policy/package-overrides.json",
    "content": "{\n  \"name\": \"referrer-policy\",\n  \"author\": \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n  \"contributors\": [],\n  \"description\": \"Middleware to set the Referrer-Policy HTTP header\",\n  \"version\": \"1.2.0\",\n  \"keywords\": [\n    \"express\",\n    \"security\",\n    \"referer\",\n    \"referrer\",\n    \"referrer-policy\",\n    \"privacy\"\n  ],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/strict-transport-security/CHANGELOG.md",
    "content": "# Changelog\n\n## 3.0.0 - Unreleased\n\n### Added\n\n- TypeScript type definitions. See [#25](https://github.com/helmetjs/hsts/pull/25)\n\n### Removed\n\n- Dropped support for `includeSubdomains` with a lowercase D. See [#231](https://github.com/helmetjs/helmet/issues/231)\n- Dropped support for `setIf`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware). See [#232](https://github.com/helmetjs/helmet/issues/232)\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 2.2.0 - 2019-03-10\n\n### Added\n\n- Created a changelog\n\n### Changed\n\n- Mark the module as Node 4+ in the `engines` field of `package.json`\n- Add a `homepage` in `package.json`\n- Add an email to `package.json`'s `bugs` field\n- Updated documentation\n- Updated Adam Baldwin's contact info. See [helmetjs/helmet#189](https://github.com/helmetjs/helmet/issues/189)\n\n### Deprecated\n\n- The `setIf` option has been deprecated and will be removed in `hsts@3`. Refer to the documentation to see how to do without it. See [#22](https://github.com/helmetjs/hsts/issues/22) for more\n- The `includeSubdomains` option (with a lowercase `d`) has been deprecated and will be removed in `hsts@3`. Use the uppercase-D `includeSubDomains` option instead. See [#21](https://github.com/helmetjs/hsts/issues/21) for more\n\nChanges in versions 2.1.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/strict-transport-security/README.md",
    "content": "# HTTP Strict Transport Security middleware\n\nThis middleware adds the `Strict-Transport-Security` header to the response. This tells browsers, \"hey, only use HTTPS for the next period of time\". ([See the spec](https://tools.ietf.org/html/rfc6797) for more.) Note that the header won't tell users on HTTP to _switch_ to HTTPS, it will just tell HTTPS users to stick around. You can enforce HTTPS with the [express-enforces-ssl](https://github.com/aredo/express-enforces-ssl) module.\n\nThis will set the Strict Transport Security header, telling browsers to visit by HTTPS for the next 365 days:\n\n```javascript\nconst strictTransportSecurity = require(\"hsts\");\n\n// Sets \"Strict-Transport-Security: max-age=31536000; includeSubDomains\"\napp.use(\n  strictTransportSecurity({\n    maxAge: 31536000, // 365 days in seconds\n  }),\n);\n```\n\nNote that the max age must be in seconds.\n\nThe `includeSubDomains` directive is present by default. If this header is set on _example.com_, supported browsers will also use HTTPS on _my-subdomain.example.com_. You can disable this:\n\n```javascript\napp.use(\n  strictTransportSecurity({\n    maxAge: 31536000,\n    includeSubDomains: false,\n  }),\n);\n```\n\nSome browsers let you submit your site's HSTS to be baked into the browser. You can add `preload` to the header with the following code. You can check your eligibility and submit your site at [hstspreload.org](https://hstspreload.org/).\n\n```javascript\napp.use(\n  strictTransportSecurity({\n    maxAge: 31536000, // Must be at least 1 year to be approved\n    includeSubDomains: true, // Must be enabled to be approved\n    preload: true,\n  }),\n);\n```\n\n[The header is ignored in insecure HTTP](https://tools.ietf.org/html/rfc6797#section-8.1), so it's safe to set in development.\n\nThis header is [somewhat well-supported by browsers](https://caniuse.com/#feat=stricttransportsecurity).\n"
  },
  {
    "path": "middlewares/strict-transport-security/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nconst DEFAULT_MAX_AGE = 365 * 24 * 60 * 60;\n\nexport interface StrictTransportSecurityOptions {\n  maxAge?: number;\n  includeSubDomains?: boolean;\n  preload?: boolean;\n}\n\nfunction parseMaxAge(value: number = DEFAULT_MAX_AGE): number {\n  if (value >= 0 && Number.isFinite(value)) {\n    return Math.floor(value);\n  } else {\n    throw new Error(\n      `Strict-Transport-Security: ${JSON.stringify(\n        value,\n      )} is not a valid value for maxAge. Please choose a positive integer.`,\n    );\n  }\n}\n\nfunction getHeaderValueFromOptions(\n  options: Readonly<StrictTransportSecurityOptions>,\n): string {\n  if (\"maxage\" in options) {\n    throw new Error(\n      \"Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?\",\n    );\n  }\n  if (\"includeSubdomains\" in options) {\n    throw new Error(\n      'Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase \"D\".)',\n    );\n  }\n\n  const directives: string[] = [`max-age=${parseMaxAge(options.maxAge)}`];\n\n  if (options.includeSubDomains === undefined || options.includeSubDomains) {\n    directives.push(\"includeSubDomains\");\n  }\n\n  if (options.preload) {\n    directives.push(\"preload\");\n  }\n\n  return directives.join(\"; \");\n}\n\nfunction strictTransportSecurity(\n  options: Readonly<StrictTransportSecurityOptions> = {},\n) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function strictTransportSecurityMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"Strict-Transport-Security\", headerValue);\n    next();\n  };\n}\n\nexport default strictTransportSecurity;\n"
  },
  {
    "path": "middlewares/strict-transport-security/package-overrides.json",
    "content": "{\n  \"name\": \"hsts\",\n  \"description\": \"HTTP Strict Transport Security middleware\",\n  \"version\": \"2.2.0\",\n  \"keywords\": [\n    \"express\",\n    \"security\",\n    \"hsts\",\n    \"strict-transport-security\",\n    \"https\"\n  ],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-content-type-options/CHANGELOG.md",
    "content": "# Changelog\n\n## 2.0.0 - Unreleased\n\n### Removed\n\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 1.1.0 - 2019-05-11\n\n### Added\n\n- Added TypeScript type definitions. See [#4](https://github.com/helmetjs/dont-sniff-mimetype/issues/4) and [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n\n### Changed\n\n- Updated some package metadata\n- Excluded some files from npm package\n\nChanges in versions 1.0.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-content-type-options/README.md",
    "content": "# X-Content-Type-Options middleware\n\nSome browsers will try to \"sniff\" mimetypes. For example, if my server serves _file.txt_ with a _text/plain_ content-type, some browsers can still run that file with `<script src=\"file.txt\"></script>`. Many browsers will allow _file.js_ to be run even if the content-type isn't for JavaScript.\n\nBrowsers' same-origin policies generally prevent remote resources from being loaded dangerously, but vulnerabilities in web browsers can cause this to be abused. Some browsers, like [Chrome](https://developers.google.com/web/updates/2018/07/site-isolation), will further isolate memory if the `X-Content-Type-Options` header is seen.\n\nThere are [some other vulnerabilities](https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/), too.\n\nThis middleware prevents Chrome, Opera 13+, IE 8+ and [Firefox 50+](https://bugzilla.mozilla.org/show_bug.cgi?id=471020) from doing this sniffing. The following example sets the `X-Content-Type-Options` header to its only option, `nosniff`:\n\n```javascript\nconst dontSniffMimetype = require(\"dont-sniff-mimetype\");\napp.use(dontSniffMimetype());\n```\n\n[MSDN has a good description](https://msdn.microsoft.com/en-us/library/gg622941%28v=vs.85%29.aspx) of how browsers behave when this header is sent.\n"
  },
  {
    "path": "middlewares/x-content-type-options/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nfunction xContentTypeOptions() {\n  return function xContentTypeOptionsMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n    next();\n  };\n}\n\nexport default xContentTypeOptions;\n"
  },
  {
    "path": "middlewares/x-content-type-options/package-overrides.json",
    "content": "{\n  \"name\": \"dont-sniff-mimetype\",\n  \"description\": \"Middleware to prevent mimetype from being sniffed\",\n  \"version\": \"1.1.0\",\n  \"keywords\": [\"express\", \"security\", \"mimetype\", \"x-content-type-options\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-dns-prefetch-control/CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n### Removed\n\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 0.3.0 - 2019-09-01\n\n### Changed\n\n- Dropped support for Node <8\n\n## 0.2.0 - 2019-05-11\n\n### Added\n\n- Added TypeScript type definitions. See [#2](https://github.com/helmetjs/dns-prefetch-control/pull/2) and [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n\n### Changed\n\n- Update some package metadata\n- Excluded some files from npm package\n\nChanges in versions 0.1.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-dns-prefetch-control/README.md",
    "content": "# X-DNS-Prefetch-Control middleware\n\nThis middleware lets you set the `X-DNS-Prefetch-Control` to control browsers' DNS prefetching. Read more about it [on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Controlling_DNS_prefetching) and [on Chromium's docs](https://dev.chromium.org/developers/design-documents/dns-prefetching).\n\nUsage:\n\n```js\nconst dnsPrefetchControl = require(\"dns-prefetch-control\");\n\n// Set X-DNS-Prefetch-Control: off\napp.use(dnsPrefetchControl());\n\n// Set X-DNS-Prefetch-Control: off\napp.use(dnsPrefetchControl({ allow: false }));\n\n// Set X-DNS-Prefetch-Control: on\napp.use(dnsPrefetchControl({ allow: true }));\n```\n"
  },
  {
    "path": "middlewares/x-dns-prefetch-control/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport interface XDnsPrefetchControlOptions {\n  allow?: boolean;\n}\n\nfunction xDnsPrefetchControl(\n  options: Readonly<XDnsPrefetchControlOptions> = {},\n) {\n  const headerValue = options.allow ? \"on\" : \"off\";\n\n  return function xDnsPrefetchControlMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ): void {\n    res.setHeader(\"X-DNS-Prefetch-Control\", headerValue);\n    next();\n  };\n}\n\nexport default xDnsPrefetchControl;\n"
  },
  {
    "path": "middlewares/x-dns-prefetch-control/package-overrides.json",
    "content": "{\n  \"name\": \"dns-prefetch-control\",\n  \"author\": \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n  \"contributors\": [],\n  \"description\": \"Middleware to set X-DNS-Prefetch-Control header.\",\n  \"version\": \"0.3.0\",\n  \"keywords\": [\"express\", \"security\", \"x-dns-prefetch-control\", \"prefetch\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-download-options/CHANGELOG.md",
    "content": "# Changelog\n\n## 2.0.0 - Unreleased\n\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 1.1.1 - 2020-06-16\n\n### Changed\n\n- Excluded more files from npm package\n\n## 1.1.0 - 2019-03-10\n\n### Added\n\n- Added TypeScript type definitions. See [#1](https://github.com/helmetjs/ienoopen/pull/1) and [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n\n### Changed\n\n- Updated documentation\n- Excluded some files from npm package\n\nChanges in versions 1.0.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-download-options/README.md",
    "content": "# X-Download-Options middleware\n\nThis middleware sets the `X-Download-Options` header to `noopen` to prevent Internet Explorer users from executing downloads in your site's context.\n\n```javascript\nconst ienoopen = require(\"ienoopen\");\napp.use(ienoopen());\n```\n\nSome web applications will serve untrusted HTML for download. By default, some versions of IE will allow you to open those HTML files _in the context of your site_, which means that an untrusted HTML page could start doing bad things in the context of your pages. For more, see [this MSDN blog post](https://docs.microsoft.com/en-us/archive/blogs/ie/ie8-security-part-v-comprehensive-protection).\n\nThis is pretty obscure, fixing a small bug on IE only. No real drawbacks other than performance/bandwidth of setting the headers, though.\n"
  },
  {
    "path": "middlewares/x-download-options/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nfunction xDownloadOptions() {\n  return function xDownloadOptionsMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ): void {\n    res.setHeader(\"X-Download-Options\", \"noopen\");\n    next();\n  };\n}\n\nexport default xDownloadOptions;\n"
  },
  {
    "path": "middlewares/x-download-options/package-overrides.json",
    "content": "{\n  \"name\": \"ienoopen\",\n  \"contributors\": [\n    \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n    \"Nathan Shively-Sanders <nathansa@microsoft.com> (https://github.com/sandersn)\"\n  ],\n  \"description\": \"Middleware to set `X-Download-Options` header for IE8 security\",\n  \"version\": \"1.1.1\",\n  \"keywords\": [\"express\", \"security\", \"x-download-options\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-frame-options/CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n### Changed\n\n- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)\n- No longer offer a specific error when trying to use `ALLOW-FROM`; it just says that it is unsupported. Only the error message has changed\n\n## 4.0.0 - 2020-12-21\n\n### Removed\n\n- Dropped support for the `ALLOW-FROM` action. [Read more here.](https://github.com/helmetjs/helmet/wiki/How-to-use-X%E2%80%93Frame%E2%80%93Options's-%60ALLOW%E2%80%93FROM%60-directive)\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 3.1.0 - 2019-05-04\n\n### Added\n\n- Added TypeScript type definitions. See [#1](https://github.com/helmetjs/frameguard/pull/16) and [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n\n### Changed\n\n- Updated some package metadata\n- Update some documentation\n- Excluded some files from npm package\n\nChanges in versions 3.0.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-frame-options/README.md",
    "content": "# X-Frame-Options middleware\n\nThe `X-Frame-Options` HTTP header restricts who can put your site in a frame which can help mitigate things like [clickjacking attacks](https://en.wikipedia.org/wiki/Clickjacking). The header has two modes: `DENY` and `SAMEORIGIN`.\n\nThis header is superseded by [the `frame-ancestors` Content Security Policy directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) but is still useful on old browsers.\n\nIf your app does not need to be framed (and most don't) you can use `DENY`. If your site can be in frames from the same origin, you can set it to `SAMEORIGIN`.\n\nUsage:\n\n```javascript\nconst frameguard = require(\"frameguard\");\n\n// Don't allow me to be in ANY frames:\napp.use(frameguard({ action: \"deny\" }));\n\n// Only let me be framed by people of the same origin:\napp.use(frameguard({ action: \"sameorigin\" }));\napp.use(frameguard()); // defaults to sameorigin\n```\n\nA legacy action, `ALLOW-FROM`, is not supported by this middleware. [Read more here.](https://helmetjs.github.io/faq/x-frame-options-allow-from-directive/)\n"
  },
  {
    "path": "middlewares/x-frame-options/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport interface XFrameOptionsOptions {\n  action?: \"deny\" | \"sameorigin\";\n}\n\nfunction getHeaderValueFromOptions({\n  action = \"sameorigin\",\n}: Readonly<XFrameOptionsOptions>): string {\n  const normalizedAction =\n    typeof action === \"string\" ? action.toUpperCase() : action;\n\n  switch (normalizedAction) {\n    case \"SAME-ORIGIN\":\n      return \"SAMEORIGIN\";\n    case \"DENY\":\n    case \"SAMEORIGIN\":\n      return normalizedAction;\n    default:\n      throw new Error(\n        `X-Frame-Options received an invalid action ${JSON.stringify(action)}`,\n      );\n  }\n}\n\nfunction xFrameOptions(options: Readonly<XFrameOptionsOptions> = {}) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function xFrameOptionsMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"X-Frame-Options\", headerValue);\n    next();\n  };\n}\n\nexport default xFrameOptions;\n"
  },
  {
    "path": "middlewares/x-frame-options/package-overrides.json",
    "content": "{\n  \"name\": \"frameguard\",\n  \"description\": \"Middleware to set X-Frame-Options headers\",\n  \"version\": \"4.0.0\",\n  \"keywords\": [\"express\", \"security\", \"x-frame-options\", \"clickjack\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-permitted-cross-domain-policies/CHANGELOG.md",
    "content": "# Changelog\n\n## Unreleased\n\n### Changed\n\n- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)\n\n### Removed\n\n- Dropped support for old Node versions. Node 14+ is now required\n\n## 0.5.0 - 2019-09-01\n\n## Changed\n\n- Dropped support for Node <8\n\n## 0.4.0 - 2019-06-15\n\n### Added\n\n- Added TypeScript type definitions. See [#7](https://github.com/helmetjs/crossdomain/issues/7)\n- Created a changelog\n- Added additional package metadata\n\n### Changed\n\n- Excluded some files from npm package\n\nChanges in versions 0.3.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-permitted-cross-domain-policies/README.md",
    "content": "# X-Permitted-Cross-Domain-Policies middleware\n\nThe `X-Permitted-Cross-Domain-Policies` header tells some web clients (like Adobe Flash or Adobe Acrobat) your domain's policy for loading cross-domain content. See the description on [OWASP](https://owasp.org/www-project-secure-headers/) for more.\n\nUsage:\n\n```javascript\nconst crossdomain = require(\"helmet-crossdomain\");\n\n// Sets X-Permitted-Cross-Domain-Policies: none\napp.use(crossdomain());\n\n// You can use any of the following values:\napp.use(crossdomain({ permittedPolicies: \"none\" }));\napp.use(crossdomain({ permittedPolicies: \"master-only\" }));\napp.use(crossdomain({ permittedPolicies: \"by-content-type\" }));\napp.use(crossdomain({ permittedPolicies: \"all\" }));\n```\n\nThe `by-ftp-type` is not currently supported. Please open an issue or pull request if you desire this feature!\n\nIf you don't expect Adobe products to load data from your site, you get a minor security benefit by adding this header.\n"
  },
  {
    "path": "middlewares/x-permitted-cross-domain-policies/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nexport interface XPermittedCrossDomainPoliciesOptions {\n  permittedPolicies?: \"none\" | \"master-only\" | \"by-content-type\" | \"all\";\n}\n\nconst ALLOWED_PERMITTED_POLICIES = new Set([\n  \"none\",\n  \"master-only\",\n  \"by-content-type\",\n  \"all\",\n]);\n\nfunction getHeaderValueFromOptions({\n  permittedPolicies = \"none\",\n}: Readonly<XPermittedCrossDomainPoliciesOptions>): string {\n  if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) {\n    return permittedPolicies;\n  } else {\n    throw new Error(\n      `X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(\n        permittedPolicies,\n      )}`,\n    );\n  }\n}\n\nfunction xPermittedCrossDomainPolicies(\n  options: Readonly<XPermittedCrossDomainPoliciesOptions> = {},\n) {\n  const headerValue = getHeaderValueFromOptions(options);\n\n  return function xPermittedCrossDomainPoliciesMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"X-Permitted-Cross-Domain-Policies\", headerValue);\n    next();\n  };\n}\n\nexport default xPermittedCrossDomainPolicies;\n"
  },
  {
    "path": "middlewares/x-permitted-cross-domain-policies/package-overrides.json",
    "content": "{\n  \"name\": \"helmet-crossdomain\",\n  \"author\": \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n  \"contributors\": [],\n  \"description\": \"Set the X-Permitted-Cross-Domain-Policies header in Express apps\",\n  \"version\": \"0.5.0\",\n  \"keywords\": [\n    \"express\",\n    \"security\",\n    \"crossdomain.xml\",\n    \"x-permitted-cross-domain-policies\"\n  ],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-powered-by/CHANGELOG.md",
    "content": "# Changelog\n\n## 2.0.0 - Unreleased\n\n### Removed\n\n- Removed `setTo` option. See [this article](https://github.com/helmetjs/helmet/wiki/How-to-set-a-custom-X%E2%80%93Powered%E2%80%93By-header) to see how to replicate the removed behavior. See [#224](https://github.com/helmetjs/helmet/issues/224).\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 1.1.0 - 2019-05-26\n\n### Added\n\n- Added TypeScript type definitions. See [#2](https://github.com/helmetjs/hide-powered-by/issues/2) and [helmetjs/helmet#188](https://github.com/helmetjs/helmet/issues/188)\n- Created a changelog\n\n### Changed\n\n- Excluded some files from npm package\n\nChanges in versions 1.0.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-powered-by/README.md",
    "content": "# X-Powered-By middleware\n\nSimple middleware to remove the `X-Powered-By` HTTP header if it's set.\n\nHackers can exploit known vulnerabilities in Express/Node if they see that your site is powered by Express (or whichever framework you use). For example, `X-Powered-By: Express` is sent in every HTTP request coming from Express, by default. This won't provide much security benefit ([as discussed here](https://github.com/expressjs/express/pull/2813#issuecomment-159270428)), but might help a tiny bit. It will also improve performance by reducing the number of bytes sent.\n\n```javascript\nconst hidePoweredBy = require(\"hide-powered-by\");\napp.use(hidePoweredBy());\n```\n\nNote: if you're using Express, you don't need this middleware and can just do this:\n\n```javascript\napp.disable(\"x-powered-by\");\n```\n"
  },
  {
    "path": "middlewares/x-powered-by/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nfunction xPoweredBy() {\n  return function xPoweredByMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.removeHeader(\"X-Powered-By\");\n    next();\n  };\n}\n\nexport default xPoweredBy;\n"
  },
  {
    "path": "middlewares/x-powered-by/package-overrides.json",
    "content": "{\n  \"name\": \"hide-powered-by\",\n  \"contributors\": [\n    \"Evan Hahn <me@evanhahn.com> (https://evanhahn.com)\",\n    \"Ameen Abdeen <ameen.abdeen.se@gmail.com>\"\n  ],\n  \"description\": \"Middleware to remove the X-Powered-By header\",\n  \"version\": \"1.1.0\",\n  \"keywords\": [\"express\", \"security\", \"x-powered-by\", \"powered-by\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "middlewares/x-xss-protection/CHANGELOG.md",
    "content": "# Changelog\n\n## 2.0.0 - 2020-08-02\n\n### Changed\n\n- XSS filtering is now disabled by default. See [#230](https://github.com/helmetjs/helmet/issues/230)\n\n### Removed\n\n- No longer accepts options. Read [\"How to disable blocking with X–XSS–Protection\"](https://github.com/helmetjs/helmet/wiki/How-to-disable-blocking-with-X%E2%80%93XSS%E2%80%93Protection) and [\"How to enable the `report` directive with X–XSS–Protection\"](https://github.com/helmetjs/helmet/wiki/How-to-enable-the-%60report%60-directive-with-X%E2%80%93XSS%E2%80%93Protection) if you need the legacy behavior.\n- Dropped support for old Node versions. Node 10+ is now required\n\n## 1.3.0 - 2019-09-01\n\n### Added\n\n- Added `mode: null` to disable `mode=block`\n\n### Changed\n\n- Minor performance improvements with Internet Explorer <9 detection\n\n## 1.2.0 - 2019-06-15\n\n### Added\n\n- Added TypeScript type definitions. See [#8](https://github.com/helmetjs/x-xss-protection/pull/8)\n- Created a changelog\n- Added some additional package metadata\n\n### Changed\n\n- Updated documentation\n- Excluded some files from npm package\n\nChanges in versions 1.1.0 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md).\n"
  },
  {
    "path": "middlewares/x-xss-protection/README.md",
    "content": "# X-XSS-Protection middleware\n\nThe `X-XSS-Protection` HTTP header aimed to offer a basic protection against cross-site scripting (XSS) attacks. _However, you probably should disable it_, which is what this middleware does.\n\nMany browsers have chosen to remove it because of the unintended security issues it creates. Generally, you should protect against XSS with sanitization and a Content Security Policy. For more, read [this GitHub issue](https://github.com/helmetjs/helmet/issues/230).\n\nThis middleware sets the `X-XSS-Protection` header to `0`. For example:\n\n```javascript\nconst xXssProtection = require(\"x-xss-protection\");\n\n// Set \"X-XSS-Protection: 0\"\napp.use(xXssProtection());\n```\n\nIf you truly need the legacy behavior, you can write your own simple middleware and avoid installing this module. For example:\n\n```javascript\n// NOTE: This is probably insecure!\napp.use((req, res, next) => {\n  res.setHeader(\"X-XSS-Protection\", \"1; mode=block\");\n  next();\n});\n```\n"
  },
  {
    "path": "middlewares/x-xss-protection/index.ts",
    "content": "import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nfunction xXssProtection() {\n  return function xXssProtectionMiddleware(\n    _req: IncomingMessage,\n    res: ServerResponse,\n    next: () => void,\n  ) {\n    res.setHeader(\"X-XSS-Protection\", \"0\");\n    next();\n  };\n}\n\nexport default xXssProtection;\n"
  },
  {
    "path": "middlewares/x-xss-protection/package-overrides.json",
    "content": "{\n  \"name\": \"x-xss-protection\",\n  \"description\": \"Middleware to disable the X-XSS-Protection header\",\n  \"version\": \"2.0.0\",\n  \"keywords\": [\"express\", \"security\", \"x-xss-protection\"],\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"version\": \"8.1.0\",\n  \"devDependencies\": {\n    \"@eslint/js\": \"^10.0.1\",\n    \"@rollup/plugin-typescript\": \"^12.3.0\",\n    \"@types/connect\": \"^3.4.38\",\n    \"@types/node\": \"^25.5.0\",\n    \"@types/node-zopfli\": \"^2.0.5\",\n    \"@types/supertest\": \"^7.2.0\",\n    \"connect\": \"^3.7.0\",\n    \"eslint\": \"^10.0.3\",\n    \"globals\": \"^17.4.0\",\n    \"node-zopfli\": \"^2.1.4\",\n    \"npm-run-all2\": \"^8.0.4\",\n    \"prettier\": \"^3.8.1\",\n    \"rollup\": \"^4.59.0\",\n    \"rollup-plugin-dts\": \"^6.4.0\",\n    \"supertest\": \"^7.2.2\",\n    \"tslib\": \"^2.8.1\",\n    \"tsx\": \"^4.21.0\",\n    \"typescript\": \"^5.9.3\",\n    \"typescript-eslint\": \"^8.57.1\"\n  },\n  \"scripts\": {\n    \"test:eslint\": \"eslint --cache .\",\n    \"test:node\": \"tsx --test test/*.ts\",\n    \"test:prettier\": \"prettier --check .\",\n    \"test:typescript\": \"tsc --noEmit\",\n    \"format\": \"prettier --write .\",\n    \"clean\": \"node ./bin/clean.mjs\",\n    \"build\": \"tsx ./build/build-package.ts\",\n    \"test\": \"run-p --aggregate-output test:*\"\n  },\n  \"type\": \"module\",\n  \"engines\": {\n    \"node\": \">=18.0.0\"\n  }\n}\n"
  },
  {
    "path": "test/content-security-policy.test.ts",
    "content": "import connect from \"connect\";\nimport assert from \"node:assert/strict\";\nimport { IncomingMessage, ServerResponse } from \"node:http\";\nimport { describe, it } from \"node:test\";\nimport supertest from \"supertest\";\nimport contentSecurityPolicy, {\n  dangerouslyDisableDefaultSrc,\n  getDefaultDirectives,\n} from \"../middlewares/content-security-policy\";\nimport { check } from \"./helpers\";\n\nconst shouldBeQuoted = [\n  \"none\",\n  \"self\",\n  \"strict-dynamic\",\n  \"report-sample\",\n  \"inline-speculation-rules\",\n  \"unsafe-inline\",\n  \"unsafe-eval\",\n  \"unsafe-hashes\",\n  \"wasm-unsafe-eval\",\n  \"nonce-abc123\",\n  \"sha256-ks9D5epDKP+c2x6DrkuHmhmfKkOM/HZ+pOlzdWbI91k=\",\n];\n\nconst getOwn = <T extends object, K extends keyof T>(\n  obj: T,\n  key: K,\n): T[K] | undefined => (Object.hasOwn(obj, key) ? obj[key] : undefined);\n\nasync function checkCsp({\n  middlewareArgs,\n  expectedHeader = \"content-security-policy\",\n  expectedDirectives,\n}: Readonly<{\n  middlewareArgs: Parameters<typeof contentSecurityPolicy>;\n  expectedHeader?: string;\n  expectedDirectives: Set<string>;\n}>): Promise<void> {\n  const { header } = await check(contentSecurityPolicy(...middlewareArgs), {});\n  const headerValue = getOwn(header, expectedHeader);\n  assert(\n    typeof headerValue === \"string\",\n    `${expectedHeader} header should be set`,\n  );\n  const actualDirectives = new Set(headerValue.split(\";\"));\n  assert.deepEqual(actualDirectives, expectedDirectives);\n}\n\ndescribe(\"Content-Security-Policy middleware\", () => {\n  it(\"sets a default policy when passed no directives\", async () => {\n    const expectedDirectives = new Set([\n      \"default-src 'self'\",\n      \"base-uri 'self'\",\n      \"font-src 'self' https: data:\",\n      \"form-action 'self'\",\n      \"frame-ancestors 'self'\",\n      \"img-src 'self' data:\",\n      \"object-src 'none'\",\n      \"script-src 'self'\",\n      \"script-src-attr 'none'\",\n      \"style-src 'self' https: 'unsafe-inline'\",\n      \"upgrade-insecure-requests\",\n    ]);\n    await checkCsp({\n      middlewareArgs: [],\n      expectedDirectives,\n    });\n    await checkCsp({\n      middlewareArgs: [{}],\n      expectedDirectives,\n    });\n    await checkCsp({\n      middlewareArgs: [Object.create(null)],\n      expectedDirectives,\n    });\n    await checkCsp({\n      middlewareArgs: [{ directives: undefined }],\n      expectedDirectives,\n    });\n    await checkCsp({\n      middlewareArgs: [{ useDefaults: true }],\n      expectedDirectives,\n    });\n  });\n\n  it(\"sets directives when named with snake-case\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": [\"'self'\"],\n            \"script-src\": [\"example.com\"],\n            \"style-src\": [\"'none'\"],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\n        \"default-src 'self'\",\n        \"script-src example.com\",\n        \"style-src 'none'\",\n      ]),\n    });\n  });\n\n  it(\"sets directives when named with camelCase\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            defaultSrc: [\"'self'\"],\n            scriptSrc: [\"example.com\"],\n            styleSrc: [\"'none'\"],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\n        \"default-src 'self'\",\n        \"script-src example.com\",\n        \"style-src 'none'\",\n      ]),\n    });\n  });\n\n  it(\"accepts a mix of snake-case and camelCase directive names\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": [\"'self'\"],\n            \"script-src\": [\"example.com\"],\n            styleSrc: [\"'none'\"],\n            objectSrc: [\"'none'\"],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\n        \"default-src 'self'\",\n        \"script-src example.com\",\n        \"style-src 'none'\",\n        \"object-src 'none'\",\n      ]),\n    });\n  });\n\n  it(\"accepts an empty list of directive values\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": [\"'self'\"],\n            sandbox: [],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\"default-src 'self'\", \"sandbox\"]),\n    });\n  });\n\n  it(\"accepts non-array iterables for directive values\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": new Set([\"'self'\"]),\n            sandbox: {\n              [Symbol.iterator]: () => ({\n                next: () => ({\n                  done: true,\n                  value: undefined,\n                }),\n              }),\n            },\n          },\n        },\n      ],\n      expectedDirectives: new Set([\"default-src 'self'\", \"sandbox\"]),\n    });\n  });\n\n  it(\"accepts strings as directive values\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": \"'self'  example.com\",\n            scriptSrc: \"'none'\",\n            sandbox: \"\",\n          },\n        },\n      ],\n      expectedDirectives: new Set([\n        \"default-src 'self'  example.com\",\n        \"script-src 'none'\",\n        \"sandbox\",\n      ]),\n    });\n  });\n\n  it(\"treats null directive values as nothing, as if they weren't set\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": \"'self'\",\n            scriptSrc: null,\n          },\n        },\n      ],\n      expectedDirectives: new Set([\"default-src 'self'\"]),\n    });\n  });\n\n  it(\"allows functions in directive values to generate dynamic directives\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": [\n              \"'self'\",\n              (req: IncomingMessage, res: ServerResponse) => {\n                assert(\n                  req instanceof IncomingMessage,\n                  \"req should be a request\",\n                );\n                assert(\n                  res instanceof ServerResponse,\n                  \"res should be a response\",\n                );\n                return \"foo.example.com\";\n              },\n              \"bar.example.com\",\n            ],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\n        \"default-src 'self' foo.example.com bar.example.com\",\n      ]),\n    });\n  });\n\n  it(\"can override the default options\", async () => {\n    const expectedDirectives = new Set([\n      \"default-src 'self' example.com\",\n      \"font-src 'self' https: data:\",\n      \"form-action 'self'\",\n      \"frame-ancestors 'self'\",\n      \"img-src 'self' data:\",\n      \"object-src 'none'\",\n      \"script-src example.com\",\n      \"script-src-attr 'none'\",\n      \"style-src 'self' https: 'unsafe-inline'\",\n      \"upgrade-insecure-requests\",\n    ]);\n\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: true,\n          directives: {\n            \"default-src\": [\"'self'\", \"example.com\"],\n            \"base-uri\": null,\n            scriptSrc: [\"example.com\"],\n          },\n        },\n      ],\n      expectedDirectives,\n    });\n\n    await checkCsp({\n      middlewareArgs: [\n        {\n          directives: {\n            \"default-src\": [\"'self'\", \"example.com\"],\n            \"base-uri\": null,\n            scriptSrc: [\"example.com\"],\n          },\n        },\n      ],\n      expectedDirectives,\n    });\n  });\n\n  it('can set the \"report only\" version of the header instead', async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": \"'self'\",\n          },\n          reportOnly: true,\n        },\n      ],\n      expectedHeader: \"content-security-policy-report-only\",\n      expectedDirectives: new Set([\"default-src 'self'\"]),\n    });\n  });\n\n  it(\"throws if any directive names are invalid\", () => {\n    const invalidNames = [\n      \"\",\n      \";\",\n      \"\\u00e1\",\n      \"default src\",\n      \"default;src\",\n      \"default,src\",\n      \"default!src\",\n      \"def\\u00e1ult-src\",\n      \"default_src\",\n      \"__proto__\",\n    ];\n    for (const name of invalidNames) {\n      assert.throws(\n        () => {\n          contentSecurityPolicy({\n            useDefaults: true,\n            directives: {\n              [name]: [\"value\"],\n            },\n          });\n        },\n        {\n          message:\n            /^Content-Security-Policy received an invalid directive name \"/,\n        },\n      );\n    }\n  });\n\n  it(\"throws if duplicate directive names are found\", () => {\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          useDefaults: false,\n          directives: {\n            defaultSrc: [\"foo\"],\n            \"default-src\": [\"foo\"],\n          },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy received a duplicate directive \"default-src\"$/,\n      },\n    );\n\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          useDefaults: false,\n          directives: {\n            defaultSrc: [\"'self'\"],\n            scriptSrc: [\"foo\"],\n            \"script-src\": [\"foo\"],\n          },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy received a duplicate directive \"script-src\"$/,\n      },\n    );\n  });\n\n  it(\"throws if any directive values are invalid\", () => {\n    const invalidValues = [\";\", \",\", \"hello;world\", \"hello,world\"];\n    for (const invalidValue of invalidValues) {\n      assert.throws(\n        () => {\n          contentSecurityPolicy({\n            useDefaults: false,\n            directives: {\n              \"default-src\": \"'self'\",\n              \"something-else\": [invalidValue],\n            },\n          });\n        },\n        {\n          message:\n            /^Content-Security-Policy received an invalid directive value for \"something-else\"$/,\n        },\n      );\n    }\n\n    for (const invalidDirectiveEntry of shouldBeQuoted) {\n      assert.throws(\n        () => {\n          contentSecurityPolicy({\n            useDefaults: false,\n            directives: {\n              \"default-src\": \"'self'\",\n              \"something-else\": [invalidDirectiveEntry],\n            },\n          });\n        },\n        {\n          message: `Content-Security-Policy received an invalid directive value for \"something-else\". \"${invalidDirectiveEntry}\" should be quoted`,\n        },\n      );\n    }\n  });\n\n  it(\"errors if any directive values are invalid when a function returns\", async () => {\n    const badDirectiveValueEntries = [\"bad;value\", ...shouldBeQuoted];\n\n    await Promise.all(\n      badDirectiveValueEntries.map(async (directiveValueEntry) => {\n        const app = connect()\n          .use(\n            contentSecurityPolicy({\n              useDefaults: false,\n              directives: {\n                defaultSrc: [\"'self'\", () => directiveValueEntry],\n              },\n            }),\n          )\n          .use(\n            (\n              err: Error,\n              _req: IncomingMessage,\n              res: ServerResponse,\n              // eslint-disable-next-line @typescript-eslint/no-unused-vars\n              _next: () => void,\n            ) => {\n              const isOk = err.message.startsWith(\n                'Content-Security-Policy received an invalid directive value for \"default-src\"',\n              );\n              res.end(JSON.stringify(isOk));\n            },\n          );\n\n        await supertest(app).get(\"/\").expect(200, \"true\");\n      }),\n    );\n  });\n\n  it(\"throws if default-src is missing\", () => {\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          useDefaults: false,\n          directives: {},\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy has no directives. Either set some or disable the header$/,\n      },\n    );\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          useDefaults: false,\n          directives: {\n            scriptSrc: [\"example.com\"],\n          },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.$/,\n      },\n    );\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          directives: { defaultSrc: null },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.$/,\n      },\n    );\n\n    // These should not throw.\n    contentSecurityPolicy({\n      useDefaults: false,\n      directives: {\n        defaultSrc: [\"foo\"],\n      },\n    });\n    contentSecurityPolicy({\n      useDefaults: false,\n      directives: {\n        \"default-src\": [\"foo\"],\n      },\n    });\n    contentSecurityPolicy({\n      useDefaults: false,\n      directives: {\n        defaultSrc: [],\n      },\n    });\n    contentSecurityPolicy({\n      useDefaults: false,\n      directives: {\n        defaultSrc: \"\",\n      },\n    });\n  });\n\n  it(\"allows default-src to be explicitly disabled\", async () => {\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            defaultSrc: dangerouslyDisableDefaultSrc,\n            scriptSrc: [\"example.com\"],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\"script-src example.com\"]),\n    });\n\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: false,\n          directives: {\n            \"default-src\": dangerouslyDisableDefaultSrc,\n            \"script-src\": [\"example.com\"],\n          },\n        },\n      ],\n      expectedDirectives: new Set([\"script-src example.com\"]),\n    });\n\n    await checkCsp({\n      middlewareArgs: [\n        {\n          useDefaults: true,\n          directives: {\n            \"default-src\": dangerouslyDisableDefaultSrc,\n          },\n        },\n      ],\n      expectedDirectives: new Set([\n        \"base-uri 'self'\",\n        \"font-src 'self' https: data:\",\n        \"form-action 'self'\",\n        \"frame-ancestors 'self'\",\n        \"img-src 'self' data:\",\n        \"object-src 'none'\",\n        \"script-src 'self'\",\n        \"script-src-attr 'none'\",\n        \"style-src 'self' https: 'unsafe-inline'\",\n        \"upgrade-insecure-requests\",\n      ]),\n    });\n  });\n\n  it(\"throws an error if default-src is disabled and there are no other directives\", () => {\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          useDefaults: false,\n          directives: {\n            defaultSrc: dangerouslyDisableDefaultSrc,\n          },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy has no directives. Either set some or disable the header$/,\n      },\n    );\n\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          useDefaults: false,\n          directives: {\n            \"default-src\": dangerouslyDisableDefaultSrc,\n          },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy has no directives. Either set some or disable the header$/,\n      },\n    );\n  });\n\n  it(\"throws an error if directives other than default-src are `dangerouslyDisableDefaultSrc`\", () => {\n    assert.throws(\n      () => {\n        contentSecurityPolicy({\n          directives: {\n            \"default-src\": \"'self'\",\n            \"script-src\": dangerouslyDisableDefaultSrc,\n          },\n        });\n      },\n      {\n        message:\n          /^Content-Security-Policy: tried to disable \"script-src\" as if it were default-src; simply omit the key$/,\n      },\n    );\n  });\n});\n\ndescribe(\"getDefaultDirectives\", () => {\n  it(\"returns the middleware's default directives\", () => {\n    assert.deepEqual(getDefaultDirectives(), {\n      \"base-uri\": [\"'self'\"],\n      \"default-src\": [\"'self'\"],\n      \"font-src\": [\"'self'\", \"https:\", \"data:\"],\n      \"form-action\": [\"'self'\"],\n      \"frame-ancestors\": [\"'self'\"],\n      \"img-src\": [\"'self'\", \"data:\"],\n      \"object-src\": [\"'none'\"],\n      \"script-src\": [\"'self'\"],\n      \"script-src-attr\": [\"'none'\"],\n      \"style-src\": [\"'self'\", \"https:\", \"'unsafe-inline'\"],\n      \"upgrade-insecure-requests\": [],\n    });\n  });\n\n  it(\"attaches itself to the top-level function\", () => {\n    assert.equal(\n      getDefaultDirectives,\n      contentSecurityPolicy.getDefaultDirectives,\n    );\n  });\n\n  it(\"returns a new copy each time\", () => {\n    const one = getDefaultDirectives();\n    one[\"worker-src\"] = [\"ignored.example\"];\n    (one[\"img-src\"] as Array<string>).push(\"ignored.example\");\n\n    const two = getDefaultDirectives();\n    assert(!(\"worker-src\" in two));\n    assert(\n      two[\"img-src\"] && !Array.from(two[\"img-src\"]).includes(\"ignored.example\"),\n    );\n  });\n});\n"
  },
  {
    "path": "test/cross-origin-embedder-policy.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport crossOriginEmbedderPolicy from \"../middlewares/cross-origin-embedder-policy\";\nimport { check } from \"./helpers\";\n\ndescribe(\"Cross-Origin-Embedder-Policy middleware\", () => {\n  it('sets \"Cross-Origin-Embedder-Policy: same-origin\" when called with no policy', async () => {\n    const expectedHeaders = {\n      \"cross-origin-embedder-policy\": \"require-corp\",\n    };\n    await check(crossOriginEmbedderPolicy(), expectedHeaders);\n    await check(crossOriginEmbedderPolicy({}), expectedHeaders);\n    await check(\n      crossOriginEmbedderPolicy(Object.create(null)),\n      expectedHeaders,\n    );\n    await check(\n      crossOriginEmbedderPolicy({ policy: undefined }),\n      expectedHeaders,\n    );\n  });\n\n  ([\"require-corp\", \"credentialless\", \"unsafe-none\"] as const).forEach(\n    (policy) => {\n      it(`sets \"Cross-Origin-Embedder-Policy: ${policy}\" when told to`, async () => {\n        await check(crossOriginEmbedderPolicy({ policy }), {\n          \"cross-origin-embedder-policy\": policy,\n        });\n      });\n    },\n  );\n\n  it(\"throws when setting the policy to an invalid value\", () => {\n    const invalidValues = [\n      \"\",\n      \"foo\",\n      \"CREDENTIALLESS\",\n      123,\n      null,\n      new String(\"credentialless\"),\n    ];\n    for (const policy of invalidValues) {\n      assert.throws(\n        () => crossOriginEmbedderPolicy({ policy: policy as any }),\n        {\n          message: /^Cross-Origin-Embedder-Policy does not support /,\n        },\n      );\n    }\n  });\n});\n"
  },
  {
    "path": "test/cross-origin-opener-policy.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport crossOriginOpenerPolicy from \"../middlewares/cross-origin-opener-policy\";\nimport { check } from \"./helpers\";\n\ndescribe(\"Cross-Origin-Opener-Policy middleware\", () => {\n  it('sets \"Cross-Origin-Opener-Policy: same-origin\" when called with no policy', async () => {\n    const expectedHeaders = {\n      \"cross-origin-opener-policy\": \"same-origin\",\n    };\n    await check(crossOriginOpenerPolicy(), expectedHeaders);\n    await check(crossOriginOpenerPolicy({}), expectedHeaders);\n    await check(crossOriginOpenerPolicy(Object.create(null)), expectedHeaders);\n    await check(\n      crossOriginOpenerPolicy({ policy: undefined }),\n      expectedHeaders,\n    );\n  });\n\n  (\n    [\n      \"same-origin\",\n      \"same-origin-allow-popups\",\n      \"noopener-allow-popups\",\n      \"unsafe-none\",\n    ] as const\n  ).forEach((policy) => {\n    it(`sets \"Cross-Origin-Opener-Policy: ${policy}\" when told to`, async () => {\n      await check(crossOriginOpenerPolicy({ policy }), {\n        \"cross-origin-opener-policy\": policy,\n      });\n    });\n  });\n\n  it(\"throws when setting the policy to an invalid value\", () => {\n    const invalidValues = [\n      \"\",\n      \"foo\",\n      \"SAME-ORIGIN\",\n      123,\n      null,\n      new String(\"same-origin\"),\n    ];\n    for (const policy of invalidValues) {\n      assert.throws(() => crossOriginOpenerPolicy({ policy: policy as any }), {\n        message: /^Cross-Origin-Opener-Policy does not support /,\n      });\n    }\n  });\n});\n"
  },
  {
    "path": "test/cross-origin-resource-policy.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport crossOriginResourcePolicy from \"../middlewares/cross-origin-resource-policy\";\nimport { check } from \"./helpers\";\n\ndescribe(\"Cross-Origin-Resource-Policy middleware\", () => {\n  it('sets \"Cross-Origin-Resource-Policy: same-origin\" when called with no policy', async () => {\n    const expectedHeaders = {\n      \"cross-origin-resource-policy\": \"same-origin\",\n    };\n    await check(crossOriginResourcePolicy(), expectedHeaders);\n    await check(crossOriginResourcePolicy({}), expectedHeaders);\n    await check(\n      crossOriginResourcePolicy(Object.create(null)),\n      expectedHeaders,\n    );\n    await check(\n      crossOriginResourcePolicy({ policy: undefined }),\n      expectedHeaders,\n    );\n  });\n\n  ([\"same-origin\", \"same-site\", \"cross-origin\"] as const).forEach((policy) => {\n    it(`sets \"Cross-Origin-Resource-Policy: ${policy}\" when told to`, async () => {\n      await check(crossOriginResourcePolicy({ policy }), {\n        \"cross-origin-resource-policy\": policy,\n      });\n    });\n  });\n\n  it(\"throws when setting the policy to an invalid value\", () => {\n    const invalidValues = [\n      \"\",\n      \"foo\",\n      \"CROSS-ORIGIN\",\n      123,\n      null,\n      new String(\"none\"),\n    ];\n    for (const policy of invalidValues) {\n      assert.throws(\n        () => crossOriginResourcePolicy({ policy: policy as any }),\n        { message: /^Cross-Origin-Resource-Policy does not support / },\n      );\n    }\n  });\n});\n"
  },
  {
    "path": "test/helpers.ts",
    "content": "import connect from \"connect\";\nimport assert from \"node:assert/strict\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport supertest from \"supertest\";\n\ntype MiddlewareFunction = (\n  req: IncomingMessage,\n  res: ServerResponse,\n  next: () => void,\n) => void;\n\nexport async function check(\n  middleware: MiddlewareFunction,\n  expectedHeaders: Readonly<Record<string, string | null>>,\n) {\n  const app = connect()\n    .use((_req, res, next) => {\n      res.setHeader(\"X-Powered-By\", \"Helmet test\");\n      next();\n    })\n    .use(middleware)\n    .use((_req: IncomingMessage, res: ServerResponse) => {\n      res.end(\"Hello world!\");\n    });\n\n  const response = await supertest(app).get(\"/\").expect(200, \"Hello world!\");\n\n  for (const [headerName, headerValue] of Object.entries(expectedHeaders)) {\n    if (headerValue === null) {\n      assert(\n        !(headerName in response.header),\n        `${headerName} should not be set`,\n      );\n    } else {\n      assert.equal(\n        response.header[headerName],\n        headerValue,\n        `${headerName} should have value ${headerValue}`,\n      );\n    }\n  }\n\n  return response;\n}\n"
  },
  {
    "path": "test/index.test.ts",
    "content": "import connect from \"connect\";\nimport assert from \"node:assert/strict\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { describe, it, type TestContext, type Mock } from \"node:test\";\nimport supertest from \"supertest\";\nimport { check } from \"./helpers\";\n\nimport * as helmet from \"..\";\n\nimport contentSecurityPolicy from \"../middlewares/content-security-policy\";\nimport crossOriginEmbedderPolicy from \"../middlewares/cross-origin-embedder-policy\";\nimport crossOriginOpenerPolicy from \"../middlewares/cross-origin-opener-policy\";\nimport crossOriginResourcePolicy from \"../middlewares/cross-origin-resource-policy\";\nimport originAgentCluster from \"../middlewares/origin-agent-cluster\";\nimport referrerPolicy from \"../middlewares/referrer-policy\";\nimport strictTransportSecurity from \"../middlewares/strict-transport-security\";\nimport xContentTypeOptions from \"../middlewares/x-content-type-options\";\nimport xDnsPrefetchControl from \"../middlewares/x-dns-prefetch-control\";\nimport xDownloadOptions from \"../middlewares/x-download-options\";\nimport xFrameOptions from \"../middlewares/x-frame-options\";\nimport xPermittedCrossDomainPolicies from \"../middlewares/x-permitted-cross-domain-policies\";\nimport xPoweredBy from \"../middlewares/x-powered-by\";\nimport xXssProtection from \"../middlewares/x-xss-protection\";\n\ndescribe(\"helmet\", () => {\n  const topLevel = helmet.default;\n\n  it(\"includes all middleware, except COEP, with their default options\", async () => {\n    // NOTE: This test relies on the CSP object being ordered a certain way,\n    // which could change (and be non-breaking). If that becomes a problem,\n    // we should update this test to be more robust.\n    const expectedHeaders = {\n      \"content-security-policy\":\n        \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\",\n      \"cross-origin-embedder-policy\": null,\n      \"cross-origin-opener-policy\": \"same-origin\",\n      \"cross-origin-resource-policy\": \"same-origin\",\n      \"origin-agent-cluster\": \"?1\",\n      \"referrer-policy\": \"no-referrer\",\n      \"strict-transport-security\": \"max-age=31536000; includeSubDomains\",\n      \"x-content-type-options\": \"nosniff\",\n      \"x-dns-prefetch-control\": \"off\",\n      \"x-download-options\": \"noopen\",\n      \"x-frame-options\": \"SAMEORIGIN\",\n      \"x-permitted-cross-domain-policies\": \"none\",\n      \"x-powered-by\": null,\n      \"x-xss-protection\": \"0\",\n    };\n\n    await check(topLevel(), expectedHeaders);\n    await check(topLevel({}), expectedHeaders);\n    await check(topLevel(Object.create(null)), expectedHeaders);\n  });\n\n  it(\"allows individual middlewares to be disabled\", async () => {\n    await check(topLevel({ contentSecurityPolicy: false }), {\n      \"content-security-policy\": null,\n    });\n    await check(topLevel({ xDnsPrefetchControl: false }), {\n      \"x-dns-prefetch-control\": null,\n    });\n  });\n\n  it(\"works with all default middlewares disabled\", async () => {\n    await check(\n      topLevel({\n        contentSecurityPolicy: false,\n        crossOriginEmbedderPolicy: false,\n        crossOriginOpenerPolicy: false,\n        crossOriginResourcePolicy: false,\n        originAgentCluster: false,\n        referrerPolicy: false,\n        strictTransportSecurity: false,\n        xContentTypeOptions: false,\n        xDnsPrefetchControl: false,\n        xDownloadOptions: false,\n        xFrameOptions: false,\n        xPermittedCrossDomainPolicies: false,\n        xPoweredBy: false,\n        xXssProtection: false,\n      }),\n      {\n        \"content-security-policy\": null,\n        \"x-frame-options\": null,\n      },\n    );\n  });\n\n  it(\"errors when `use`d directly\", () => {\n    const fakeRequest = {\n      constructor: {\n        name: \"IncomingMessage\",\n      },\n    };\n\n    assert.throws(() => topLevel(fakeRequest as any));\n  });\n\n  it(\"allows default middleware to be explicitly enabled (a no-op)\", async () => {\n    await check(topLevel({ xFrameOptions: true }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n  });\n\n  it(\"allows Cross-Origin-Embedder-Policy middleware to be explicitly enabled\", async () => {\n    await check(topLevel({ crossOriginEmbedderPolicy: true }), {\n      \"cross-origin-embedder-policy\": \"require-corp\",\n    });\n  });\n\n  it(\"allows Cross-Origin-Embedder-Policy middleware to be explicitly disabled\", async () => {\n    await check(topLevel({ crossOriginEmbedderPolicy: false }), {\n      \"cross-origin-embedder-policy\": null,\n    });\n  });\n\n  it(\"allows Cross-Origin-Embedder-Policy middleware to be enabled with custom arguments\", async () => {\n    await check(\n      topLevel({ crossOriginEmbedderPolicy: { policy: \"credentialless\" } }),\n      {\n        \"cross-origin-embedder-policy\": \"credentialless\",\n      },\n    );\n  });\n\n  it(\"allows Cross-Origin-Opener-Policy middleware to be enabled with its default\", async () => {\n    await check(topLevel({ crossOriginOpenerPolicy: true }), {\n      \"cross-origin-opener-policy\": \"same-origin\",\n    });\n  });\n\n  it(\"allows Cross-Origin-Opener-Policy middleware to be enabled with custom arguments\", async () => {\n    await check(\n      topLevel({\n        crossOriginOpenerPolicy: { policy: \"same-origin-allow-popups\" },\n      }),\n      {\n        \"cross-origin-opener-policy\": \"same-origin-allow-popups\",\n      },\n    );\n  });\n\n  it(\"allows Cross-Origin-Opener-Policy middleware to be explicitly disabled\", async () => {\n    await check(topLevel({ crossOriginOpenerPolicy: false }), {\n      \"cross-origin-opener-policy\": null,\n    });\n  });\n\n  it(\"allows Cross-Origin-Resource-Policy middleware to be enabled with its default\", async () => {\n    await check(topLevel({ crossOriginResourcePolicy: true }), {\n      \"cross-origin-resource-policy\": \"same-origin\",\n    });\n  });\n\n  it(\"allows Cross-Origin-Resource-Policy middleware to be enabled with custom arguments\", async () => {\n    await check(\n      topLevel({ crossOriginResourcePolicy: { policy: \"same-site\" } }),\n      {\n        \"cross-origin-resource-policy\": \"same-site\",\n      },\n    );\n  });\n\n  it(\"allows Cross-Origin-Resource-Policy middleware to be explicitly disabled\", async () => {\n    await check(topLevel({ crossOriginResourcePolicy: false }), {\n      \"cross-origin-resource-policy\": null,\n    });\n  });\n\n  it(\"allows Origin-Agent-Cluster middleware to be enabled\", async () => {\n    await check(topLevel({ originAgentCluster: true }), {\n      \"origin-agent-cluster\": \"?1\",\n    });\n  });\n\n  it(\"allows Origin-Agent-Cluster middleware to be explicitly disabled\", async () => {\n    await check(topLevel({ originAgentCluster: false }), {\n      \"origin-agent-cluster\": null,\n    });\n  });\n\n  it(\"properly handles a middleware calling `next()` with an error\", async () => {\n    const app = connect()\n      .use(\n        topLevel({\n          contentSecurityPolicy: {\n            directives: {\n              defaultSrc: [\"'self'\", () => \"bad;value\"],\n            },\n          },\n        }),\n      )\n      .use(\n        (\n          err: Error,\n          _req: IncomingMessage,\n          res: ServerResponse,\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          _next: () => void,\n        ) => {\n          res.statusCode = 500;\n          res.setHeader(\"Content-Type\", \"application/json\");\n          res.end(JSON.stringify({ message: err.message }));\n        },\n      );\n\n    await supertest(app).get(\"/\").expect(500, {\n      message:\n        'Content-Security-Policy received an invalid directive value for \"default-src\"',\n    });\n  });\n\n  describe(\"warnings\", () => {\n    const mockWarn = (t: TestContext) =>\n      t.mock.method(console, \"warn\", () => {});\n\n    const assertWarns = (\n      { mock }: Mock<() => unknown>,\n      message: string,\n    ): void => {\n      assert.equal(mock.callCount(), 1);\n      assert.deepEqual(mock.calls[0]?.arguments, [message]);\n    };\n\n    it(\"logs a warning when passing options to xPoweredBy\", (t) => {\n      const warn = mockWarn(t);\n      topLevel({ xPoweredBy: { setTo: \"deprecated option\" } as any });\n      assertWarns(\n        warn,\n        \"X-Powered-By does not take options. Remove the property to silence this warning.\",\n      );\n    });\n\n    it(\"logs a warning when passing options to xDownloadOptions\", (t) => {\n      const warn = mockWarn(t);\n      topLevel({ xDownloadOptions: { option: \"foo\" } as any });\n      assertWarns(\n        warn,\n        \"X-Download-Options does not take options. Remove the property to silence this warning.\",\n      );\n    });\n\n    it(\"logs a warning when passing options to originAgentCluster\", (t) => {\n      const warn = mockWarn(t);\n      topLevel({ originAgentCluster: { option: \"foo\" } as any });\n      assertWarns(\n        warn,\n        \"Origin-Agent-Cluster does not take options. Remove the property to silence this warning.\",\n      );\n    });\n\n    it(\"logs a warning when passing options to xContentTypeOptions\", (t) => {\n      const warn = mockWarn(t);\n      topLevel({ xContentTypeOptions: { option: \"foo\" } as any });\n      assertWarns(\n        warn,\n        \"X-Content-Type-Options does not take options. Remove the property to silence this warning.\",\n      );\n    });\n\n    it(\"logs a warning when passing options to xXssProtection\", (t) => {\n      const warn = mockWarn(t);\n      topLevel({ xXssProtection: { setOnOldIe: true } as any });\n      assertWarns(\n        warn,\n        \"X-XSS-Protection does not take options. Remove the property to silence this warning.\",\n      );\n    });\n  });\n\n  it(\"exposes standalone middleware\", () => {\n    assert.strictEqual(\n      helmet.contentSecurityPolicy.name,\n      contentSecurityPolicy.name,\n    );\n    assert.strictEqual(\n      helmet.contentSecurityPolicy.name,\n      \"contentSecurityPolicy\",\n    );\n\n    assert.strictEqual(\n      helmet.crossOriginEmbedderPolicy.name,\n      crossOriginEmbedderPolicy.name,\n    );\n    assert.strictEqual(\n      helmet.crossOriginEmbedderPolicy.name,\n      \"crossOriginEmbedderPolicy\",\n    );\n\n    assert.strictEqual(\n      helmet.crossOriginOpenerPolicy.name,\n      crossOriginOpenerPolicy.name,\n    );\n    assert.strictEqual(\n      helmet.crossOriginOpenerPolicy.name,\n      \"crossOriginOpenerPolicy\",\n    );\n\n    assert.strictEqual(\n      helmet.crossOriginResourcePolicy.name,\n      crossOriginResourcePolicy.name,\n    );\n    assert.strictEqual(\n      helmet.crossOriginResourcePolicy.name,\n      \"crossOriginResourcePolicy\",\n    );\n\n    assert.strictEqual(helmet.originAgentCluster.name, originAgentCluster.name);\n    assert.strictEqual(helmet.originAgentCluster.name, \"originAgentCluster\");\n\n    assert.strictEqual(helmet.referrerPolicy.name, referrerPolicy.name);\n    assert.strictEqual(helmet.referrerPolicy.name, \"referrerPolicy\");\n\n    assert.strictEqual(\n      helmet.strictTransportSecurity.name,\n      strictTransportSecurity.name,\n    );\n    assert.strictEqual(\n      helmet.strictTransportSecurity.name,\n      \"strictTransportSecurity\",\n    );\n\n    assert.strictEqual(\n      helmet.xContentTypeOptions.name,\n      xContentTypeOptions.name,\n    );\n    assert.strictEqual(helmet.xContentTypeOptions.name, \"xContentTypeOptions\");\n\n    assert.strictEqual(\n      helmet.xDnsPrefetchControl.name,\n      xDnsPrefetchControl.name,\n    );\n    assert.strictEqual(helmet.xDnsPrefetchControl.name, \"xDnsPrefetchControl\");\n\n    assert.strictEqual(helmet.xDownloadOptions.name, xDownloadOptions.name);\n    assert.strictEqual(helmet.xDownloadOptions.name, \"xDownloadOptions\");\n\n    assert.strictEqual(helmet.xFrameOptions.name, xFrameOptions.name);\n    assert.strictEqual(helmet.xFrameOptions.name, \"xFrameOptions\");\n\n    assert.strictEqual(\n      helmet.xPermittedCrossDomainPolicies.name,\n      xPermittedCrossDomainPolicies.name,\n    );\n    assert.strictEqual(\n      helmet.xPermittedCrossDomainPolicies.name,\n      \"xPermittedCrossDomainPolicies\",\n    );\n\n    assert.strictEqual(helmet.xPoweredBy.name, xPoweredBy.name);\n    assert.strictEqual(helmet.xPoweredBy.name, \"xPoweredBy\");\n\n    assert.strictEqual(helmet.xXssProtection.name, xXssProtection.name);\n    assert.strictEqual(helmet.xXssProtection.name, \"xXssProtection\");\n  });\n\n  it(\"exposes legacy header options\", async () => {\n    await check(topLevel({ hsts: { maxAge: 123 } }), {\n      \"strict-transport-security\": \"max-age=123; includeSubDomains\",\n    });\n    await check(topLevel({ noSniff: false }), {\n      \"x-content-type-options\": null,\n    });\n    await check(topLevel({ dnsPrefetchControl: { allow: true } }), {\n      \"x-dns-prefetch-control\": \"on\",\n    });\n    await check(topLevel({ ieNoOpen: false }), {\n      \"x-download-options\": null,\n    });\n    await check(topLevel({ frameguard: { action: \"deny\" } }), {\n      \"x-frame-options\": \"DENY\",\n    });\n    await check(\n      topLevel({\n        permittedCrossDomainPolicies: { permittedPolicies: \"by-content-type\" },\n      }),\n      {\n        \"x-permitted-cross-domain-policies\": \"by-content-type\",\n      },\n    );\n    await check(topLevel({ hidePoweredBy: false }), {\n      \"x-powered-by\": \"Helmet test\",\n    });\n    await check(topLevel({ xssFilter: false }), {\n      \"x-xss-protection\": null,\n    });\n  });\n\n  it(\"errors with conflicting header options (legacy + new)\", () => {\n    assert.throws(() =>\n      topLevel({ strictTransportSecurity: true, hsts: true } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({ xContentTypeOptions: true, noSniff: true } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({ xDnsPrefetchControl: true, dnsPrefetchControl: true } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({ xDownloadOptions: true, ieNoOpen: true } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({ xFrameOptions: true, frameguard: true } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({\n        xPermittedCrossDomainPolicies: true,\n        permittedCrossDomainPolicies: true,\n      } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({ xPoweredBy: true, hidePoweredBy: true } as any),\n    );\n\n    assert.throws(() =>\n      topLevel({ xXssProtection: true, xssFilter: true } as any),\n    );\n  });\n\n  it(\"exposes standalone middleware with legacy aliases\", () => {\n    assert.strictEqual(helmet.hsts.name, strictTransportSecurity.name);\n    assert.strictEqual(\n      helmet.dnsPrefetchControl.name,\n      xDnsPrefetchControl.name,\n    );\n    assert.strictEqual(helmet.ieNoOpen.name, xDownloadOptions.name);\n    assert.strictEqual(helmet.frameguard.name, xFrameOptions.name);\n    assert.strictEqual(helmet.noSniff.name, xContentTypeOptions.name);\n    assert.strictEqual(helmet.hidePoweredBy.name, xPoweredBy.name);\n    assert.strictEqual(\n      helmet.permittedCrossDomainPolicies.name,\n      xPermittedCrossDomainPolicies.name,\n    );\n    assert.strictEqual(helmet.xssFilter.name, xXssProtection.name);\n  });\n});\n"
  },
  {
    "path": "test/origin-agent-cluster.test.ts",
    "content": "import { describe, it } from \"node:test\";\nimport originAgentCluster from \"../middlewares/origin-agent-cluster\";\nimport { check } from \"./helpers\";\n\ndescribe(\"Origin-Agent-Cluster middleware\", () => {\n  it('sets \"Origin-Agent-Cluster: ?1\"', async () => {\n    await check(originAgentCluster(), {\n      \"origin-agent-cluster\": \"?1\",\n    });\n  });\n});\n"
  },
  {
    "path": "test/project-setups/.gitignore",
    "content": "node_modules/"
  },
  {
    "path": "test/project-setups/javascript-commonjs/check.js",
    "content": "const connect = require(\"connect\");\nconst supertest = require(\"supertest\");\nconst helmet = require(\"helmet\");\n\nconst handler = (_, res) => res.end(\"Hello world\");\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/javascript-commonjs/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"commonjs\",\n  \"scripts\": {\n    \"helmet:test\": \"node check.js\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/javascript-commonjs-default-member/check.js",
    "content": "const connect = require(\"connect\");\nconst supertest = require(\"supertest\");\nconst { default: helmet, frameguard } = require(\"helmet\");\n\nconst handler = (_, res) => res.end(\"Hello world\");\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/javascript-commonjs-default-member/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"commonjs\",\n  \"scripts\": {\n    \"helmet:test\": \"node check.js\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/javascript-esm/check.js",
    "content": "import connect from \"connect\";\nimport helmet, { frameguard } from \"helmet\";\nimport supertest from \"supertest\";\n\nconst handler = (_, res) => res.end(\"Hello world\");\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testImportedMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function testAttachedMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testImportedMiddleware();\n  await testAttachedMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/javascript-esm/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"helmet:test\": \"node check.js\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-commonjs/check.ts",
    "content": "import connect from \"connect\";\nimport helmet, { frameguard } from \"helmet\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport supertest from \"supertest\";\n\nconst handler = (_: IncomingMessage, res: ServerResponse) => {\n  res.end(\"Hello world\");\n};\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testImportedMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function testAttachedMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testImportedMiddleware();\n  await testAttachedMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/typescript-commonjs/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"commonjs\",\n  \"scripts\": {\n    \"helmet:test\": \"tsx check.ts\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-commonjs/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node\",\n    \"esModuleInterop\": true\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-commonjs-nodenext-moduleResolution/check.ts",
    "content": "import connect from \"connect\";\nimport helmet, { frameguard } from \"helmet\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport supertest from \"supertest\";\n\nconst handler = (_: IncomingMessage, res: ServerResponse) => {\n  res.end(\"Hello world\");\n};\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testImportedMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function testAttachedMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testImportedMiddleware();\n  await testAttachedMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/typescript-commonjs-nodenext-moduleResolution/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"commonjs\",\n  \"scripts\": {\n    \"helmet:test\": \"tsx check.ts\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-commonjs-nodenext-moduleResolution/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"nodenext\",\n    \"esModuleInterop\": true\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-esnext/check.ts",
    "content": "import connect from \"connect\";\nimport helmet, { frameguard } from \"helmet\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport supertest from \"supertest\";\n\nconst handler = (_: IncomingMessage, res: ServerResponse) => {\n  res.end(\"Hello world\");\n};\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testImportedMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function testAttachedMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testImportedMiddleware();\n  await testAttachedMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/typescript-esnext/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"helmet:test\": \"tsx check.ts\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-esnext/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-nodenext-commonjs/check.ts",
    "content": "import connect from \"connect\";\nimport helmet, { frameguard } from \"helmet\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport supertest from \"supertest\";\n\nconst handler = (_: IncomingMessage, res: ServerResponse) => {\n  res.end(\"Hello world\");\n};\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testImportedMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function testAttachedMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testImportedMiddleware();\n  await testAttachedMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/typescript-nodenext-commonjs/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"commonjs\",\n  \"scripts\": {\n    \"helmet:test\": \"tsx check.ts\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-nodenext-commonjs/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"moduleResolution\": \"nodenext\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-nodenext-esm/check.ts",
    "content": "import connect from \"connect\";\nimport helmet, { frameguard } from \"helmet\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport supertest from \"supertest\";\n\nconst handler = (_: IncomingMessage, res: ServerResponse) => {\n  res.end(\"Hello world\");\n};\n\nasync function testTopLevel() {\n  const app = connect().use(helmet()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-download-options\", \"noopen\");\n}\n\nasync function testImportedMiddleware() {\n  const app = connect().use(frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function testAttachedMiddleware() {\n  const app = connect().use(helmet.frameguard()).use(handler);\n  await supertest(app)\n    .get(\"/\")\n    .expect(200, \"Hello world\")\n    .expect(\"x-frame-options\", \"SAMEORIGIN\");\n}\n\nasync function main() {\n  await testTopLevel();\n  await testImportedMiddleware();\n  await testAttachedMiddleware();\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});\n"
  },
  {
    "path": "test/project-setups/typescript-nodenext-esm/package.json",
    "content": "{\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"helmet:test\": \"tsx check.ts\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups/typescript-nodenext-esm/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"moduleResolution\": \"nodenext\"\n  }\n}\n"
  },
  {
    "path": "test/project-setups.test.ts",
    "content": "import * as childProcess from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport test from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { promisify } from \"node:util\";\nimport { npm } from \"../build/helpers.js\";\n\nconst exec = promisify(childProcess.exec);\n\nconst projectSetupsFolder = fileURLToPath(\n  new URL(\"./project-setups\", import.meta.url),\n);\nconst projectSetups = fs\n  .readdirSync(projectSetupsFolder, { withFileTypes: true })\n  .filter((dirent) => dirent.isDirectory())\n  .map((dirent) => dirent.name);\n\nasync function buildHelmet(): Promise<string> {\n  // Unfortunately, we can't import `buildAndPack` directly.\n  // Run it and get the last line: the tarball path.\n  const { stdout } = await exec(\"npm run build\");\n  const lines = stdout.trim().split(/\\r?\\n/g);\n  const result = lines[lines.length - 1]?.trim();\n  if (!result) {\n    throw new Error(\"Couldn't parse tarball path from build output\");\n  }\n  return result;\n}\n\nlet helmetTarballPromise: undefined | Promise<string>;\nasync function getHelmetTarballPath(): Promise<string> {\n  if (!helmetTarballPromise) {\n    helmetTarballPromise = buildHelmet();\n  }\n  return helmetTarballPromise;\n}\n\nfor (const projectSetupName of projectSetups) {\n  test(`${projectSetupName} project setup`, { timeout: 60_000 }, async () => {\n    const projectFolder = path.join(projectSetupsFolder, projectSetupName);\n    const nodeModulesFolder = path.join(projectFolder, \"node_modules\");\n\n    await fs.promises.rm(nodeModulesFolder, { recursive: true, force: true });\n\n    await npm(\n      [\"install\", \"--no-save\", \"--no-audit\", await getHelmetTarballPath()],\n      {\n        cwd: projectFolder,\n      },\n    );\n\n    await npm([\"run\", \"helmet:test\"], { cwd: projectFolder });\n  });\n}\n"
  },
  {
    "path": "test/referrer-policy.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport referrerPolicy from \"../middlewares/referrer-policy\";\nimport { check } from \"./helpers\";\n\ndescribe(\"Referrer-Policy middleware\", () => {\n  it(\"sets header to no-referrer when passed no policy\", async () => {\n    await check(referrerPolicy(), {\n      \"referrer-policy\": \"no-referrer\",\n    });\n    await check(referrerPolicy({}), {\n      \"referrer-policy\": \"no-referrer\",\n    });\n    await check(referrerPolicy(Object.create(null)), {\n      \"referrer-policy\": \"no-referrer\",\n    });\n    await check(referrerPolicy({ policy: undefined }), {\n      \"referrer-policy\": \"no-referrer\",\n    });\n  });\n\n  (\n    [\n      \"no-referrer\",\n      \"no-referrer-when-downgrade\",\n      \"same-origin\",\n      \"origin\",\n      \"strict-origin\",\n      \"origin-when-cross-origin\",\n      \"strict-origin-when-cross-origin\",\n      \"unsafe-url\",\n      \"\",\n    ] as const\n  ).forEach((policy) => {\n    it(`can set the header to \"${policy}\" by specifying it as a string`, async () => {\n      await check(referrerPolicy({ policy }), {\n        \"referrer-policy\": policy,\n      });\n    });\n\n    it(`can set the header to \"${policy}\" by specifying it as an array string`, async () => {\n      await check(referrerPolicy({ policy: [policy] }), {\n        \"referrer-policy\": policy,\n      });\n    });\n  });\n\n  it(\"can set an array with multiple values\", async () => {\n    await check(referrerPolicy({ policy: [\"origin\", \"unsafe-url\"] }), {\n      \"referrer-policy\": \"origin,unsafe-url\",\n    });\n  });\n\n  it(\"fails with a bad policy\", () => {\n    const invalidValues = [\"foo\", \"sameorigin\", \"ORIGIN\", 123, false, null, {}];\n    for (const policy of invalidValues) {\n      assert.throws(() => referrerPolicy({ policy: policy as any }));\n    }\n  });\n\n  it(\"fails with an empty array\", () => {\n    assert.throws(() => referrerPolicy({ policy: [] }));\n  });\n\n  it(\"fails with duplicate values\", () => {\n    assert.throws(() => referrerPolicy({ policy: [\"origin\", \"origin\"] }));\n    assert.throws(() =>\n      referrerPolicy({ policy: [\"same-origin\", \"origin\", \"same-origin\"] }),\n    );\n  });\n});\n"
  },
  {
    "path": "test/source-files.test.ts",
    "content": "import * as childProcess from \"node:child_process\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { describe, it } from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { promisify } from \"node:util\";\n\nconst EXTNAMES_THAT_DONT_HAVE_TO_BE_ASCII: ReadonlySet<string> = new Set([\n  \".md\",\n]);\nconst NEWLINE = \"\\n\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\nconst TILDE = \"~\".charCodeAt(0);\n\nconst exec = promisify(childProcess.exec);\n\nconst filename = fileURLToPath(import.meta.url);\nconst root = path.resolve(path.dirname(filename), \"..\");\n\ndescribe(\"source files\", () => {\n  it('only has \"normal\" ASCII characters in the source files', async () => {\n    const sourceFiles = await getSourceFiles();\n    for (const { path, contents } of sourceFiles) {\n      const abnormalByteIndex = contents.findIndex(\n        (byte) => !isNormalAsciiByte(byte),\n      );\n      if (abnormalByteIndex !== -1) {\n        throw new Error(\n          `${path} must only contain \"normal\" ASCII characters but contained abnormal byte at ${abnormalByteIndex}`,\n        );\n      }\n    }\n  });\n});\n\nconst getSourceFiles = async (): Promise<\n  Iterable<{ path: string; contents: Uint8Array }>\n> => {\n  const paths = await getSourceFilePaths();\n  return Promise.all(\n    paths.map(async (path) => ({\n      path,\n      contents: await fs.readFile(path),\n    })),\n  );\n};\n\nconst getSourceFilePaths = async (): Promise<Array<string>> =>\n  (await exec(\"git ls-files\", { cwd: root })).stdout\n    .split(/\\r?\\n/g)\n    .filter(\n      (file) => !EXTNAMES_THAT_DONT_HAVE_TO_BE_ASCII.has(path.extname(file)),\n    )\n    .filter(Boolean)\n    .map((line) => path.resolve(root, line));\n\nconst isNormalAsciiByte = (byte: number): boolean =>\n  byte === NEWLINE || (byte >= SPACE && byte <= TILDE);\n"
  },
  {
    "path": "test/strict-transport-security.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport strictTransportSecurity from \"../middlewares/strict-transport-security\";\nimport { check } from \"./helpers\";\n\ndescribe(\"Strict-Transport-Security middleware\", () => {\n  it('by default, sets max-age to 365 days and adds \"includeSubDomains\"', async () => {\n    assert.equal(31536000, 365 * 24 * 60 * 60);\n\n    const expectedHeaders = {\n      \"strict-transport-security\": \"max-age=31536000; includeSubDomains\",\n    };\n\n    await check(strictTransportSecurity(), expectedHeaders);\n    await check(strictTransportSecurity({}), expectedHeaders);\n    await check(strictTransportSecurity(Object.create(null)), expectedHeaders);\n    await check(\n      strictTransportSecurity({ maxAge: undefined }),\n      expectedHeaders,\n    );\n    await check(\n      strictTransportSecurity({ includeSubDomains: undefined }),\n      expectedHeaders,\n    );\n  });\n\n  it(\"sets the max-age to a non-negative integer\", async () => {\n    await check(strictTransportSecurity({ maxAge: 1234 }), {\n      \"strict-transport-security\": \"max-age=1234; includeSubDomains\",\n    });\n    await check(strictTransportSecurity({ maxAge: 0 }), {\n      \"strict-transport-security\": \"max-age=0; includeSubDomains\",\n    });\n    await check(strictTransportSecurity({ maxAge: -0 }), {\n      \"strict-transport-security\": \"max-age=0; includeSubDomains\",\n    });\n  });\n\n  it(\"rounds non-integer max-ages down\", async () => {\n    await check(strictTransportSecurity({ maxAge: 123.4 }), {\n      \"strict-transport-security\": \"max-age=123; includeSubDomains\",\n    });\n    await check(strictTransportSecurity({ maxAge: 123.5 }), {\n      \"strict-transport-security\": \"max-age=123; includeSubDomains\",\n    });\n  });\n\n  it(\"disables subdomains with the includeSubDomains option\", async () => {\n    await check(strictTransportSecurity({ includeSubDomains: false }), {\n      \"strict-transport-security\": \"max-age=31536000\",\n    });\n  });\n\n  it(\"can enable preloading\", async () => {\n    await check(strictTransportSecurity({ preload: true }), {\n      \"strict-transport-security\":\n        \"max-age=31536000; includeSubDomains; preload\",\n    });\n  });\n\n  it(\"can explicitly disable preloading\", async () => {\n    await check(strictTransportSecurity({ preload: false }), {\n      \"strict-transport-security\": \"max-age=31536000; includeSubDomains\",\n    });\n  });\n\n  it(\"throws an error with invalid parameters\", () => {\n    assert.throws(() => strictTransportSecurity({ maxAge: -123 }));\n    assert.throws(() =>\n      strictTransportSecurity({ maxAge: BigInt(-123) as any }),\n    );\n    assert.throws(() => strictTransportSecurity({ maxAge: -0.1 }));\n    assert.throws(() => strictTransportSecurity({ maxAge: Infinity }));\n    assert.throws(() => strictTransportSecurity({ maxAge: -Infinity }));\n    assert.throws(() => strictTransportSecurity({ maxAge: NaN }));\n\n    assert.throws(() => strictTransportSecurity({ maxAge: \"123\" } as any));\n    assert.throws(() =>\n      strictTransportSecurity({ maxAge: BigInt(123) } as any),\n    );\n    assert.throws(() => strictTransportSecurity({ maxAge: true } as any));\n    assert.throws(() => strictTransportSecurity({ maxAge: false } as any));\n    assert.throws(() => strictTransportSecurity({ maxAge: {} } as any));\n    assert.throws(() => strictTransportSecurity({ maxAge: [] } as any));\n    assert.throws(() => strictTransportSecurity({ maxAge: null } as any));\n\n    assert.throws(() => strictTransportSecurity({ maxage: false } as any));\n    assert.throws(() => strictTransportSecurity({ maxage: 1234 } as any));\n  });\n\n  it(\"logs a warning when using the mis-capitalized `includeSubdomains` parameter\", () => {\n    assert.throws(\n      () => strictTransportSecurity({ includeSubdomains: false } as any),\n      {\n        message:\n          'Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase \"D\".)',\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/x-content-type-options.test.ts",
    "content": "import { describe, it } from \"node:test\";\nimport xContentTypeOptions from \"../middlewares/x-content-type-options\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-Content-Type-Options middleware\", () => {\n  it('sets \"X-Content-Type-Options: nosniff\"', async () => {\n    await check(xContentTypeOptions(), {\n      \"x-content-type-options\": \"nosniff\",\n    });\n  });\n});\n"
  },
  {
    "path": "test/x-dns-prefetch-control.test.ts",
    "content": "import { describe, it } from \"node:test\";\nimport xDnsPrefetchControl from \"../middlewares/x-dns-prefetch-control\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-DNS-Prefetch-Control middleware\", () => {\n  it('sets the header to \"off\" by default', async () => {\n    const expectedHeaders = { \"x-dns-prefetch-control\": \"off\" };\n\n    await check(xDnsPrefetchControl(), expectedHeaders);\n    await check(xDnsPrefetchControl({}), expectedHeaders);\n    await check(xDnsPrefetchControl(Object.create(null)), expectedHeaders);\n  });\n\n  it('can set header to \"off\" with configuration', async () => {\n    await check(xDnsPrefetchControl({ allow: false }), {\n      \"x-dns-prefetch-control\": \"off\",\n    });\n  });\n\n  it('can set header to \"on\" with configuration', async () => {\n    await check(xDnsPrefetchControl({ allow: true }), {\n      \"x-dns-prefetch-control\": \"on\",\n    });\n  });\n});\n"
  },
  {
    "path": "test/x-download-options.test.ts",
    "content": "import { describe, it } from \"node:test\";\nimport xDownloadOptions from \"../middlewares/x-download-options\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-Download-Options middleware\", () => {\n  it('sets \"X-Download-Options: noopen\"', async () => {\n    await check(xDownloadOptions(), {\n      \"x-download-options\": \"noopen\",\n    });\n  });\n});\n"
  },
  {
    "path": "test/x-frame-options.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport xFrameOptions from \"../middlewares/x-frame-options\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-Frame-Options middleware\", () => {\n  it('sets \"X-Frame-Options: SAMEORIGIN\" when passed no action', async () => {\n    await check(xFrameOptions(), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n    await check(xFrameOptions({}), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n    await check(xFrameOptions(Object.create(null)), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n    await check(xFrameOptions({ action: undefined }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n  });\n\n  it('can set \"X-Frame-Options: DENY\"', async () => {\n    await check(xFrameOptions({ action: \"deny\" }), {\n      \"x-frame-options\": \"DENY\",\n    });\n\n    // These are not allowed by the types, but are supported.\n    await check(xFrameOptions({ action: \"DENY\" as any }), {\n      \"x-frame-options\": \"DENY\",\n    });\n    await check(xFrameOptions({ action: \"deNY\" as any }), {\n      \"x-frame-options\": \"DENY\",\n    });\n  });\n\n  it('can set \"X-Frame-Options: SAMEORIGIN\" when specified', async () => {\n    await check(xFrameOptions({ action: \"sameorigin\" }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n\n    // These are not allowed by the types, but are supported.\n    await check(xFrameOptions({ action: \"SAMEORIGIN\" as any }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n    await check(xFrameOptions({ action: \"sameORIGIN\" as any }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n    await check(xFrameOptions({ action: \"SAME-ORIGIN\" as any }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n    await check(xFrameOptions({ action: \"same-origin\" as any }), {\n      \"x-frame-options\": \"SAMEORIGIN\",\n    });\n  });\n\n  it(\"throws when passed invalid actions\", () => {\n    for (const action of [\n      \"\",\n      \"foo\",\n      \" deny\",\n      \"allow-from\",\n      \"ALLOW-FROM\",\n      123,\n      null,\n      new String(\"SAMEORIGIN\"),\n    ]) {\n      assert.throws(() => xFrameOptions({ action: action as any }), {\n        message: /^X-Frame-Options received an invalid action /,\n      });\n    }\n  });\n});\n"
  },
  {
    "path": "test/x-permitted-cross-domain-policies.test.ts",
    "content": "import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\nimport xPermittedCrossDomainPolicies from \"../middlewares/x-permitted-cross-domain-policies\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-Permitted-Cross-Domain-Policies middleware\", () => {\n  it('sets \"X-Permitted-Cross-Domain-Policies: none\" when called with no permitted policies', async () => {\n    const expectedHeaders = {\n      \"x-permitted-cross-domain-policies\": \"none\",\n    };\n    await check(xPermittedCrossDomainPolicies(), expectedHeaders);\n    await check(xPermittedCrossDomainPolicies({}), expectedHeaders);\n    await check(\n      xPermittedCrossDomainPolicies(Object.create(null)),\n      expectedHeaders,\n    );\n    await check(\n      xPermittedCrossDomainPolicies({ permittedPolicies: undefined }),\n      expectedHeaders,\n    );\n  });\n\n  ([\"none\", \"master-only\", \"by-content-type\", \"all\"] as const).forEach(\n    (permittedPolicies) => {\n      it(`sets \"X-Permitted-Cross-Domain-Policies: ${permittedPolicies}\" when told to`, async () => {\n        await check(xPermittedCrossDomainPolicies({ permittedPolicies }), {\n          \"x-permitted-cross-domain-policies\": permittedPolicies,\n        });\n      });\n    },\n  );\n\n  it(\"throws when setting the policy to an invalid value\", () => {\n    const invalidValues = [\n      \"\",\n      \"NONE\",\n      \"by-ftp-filename\",\n      123,\n      null,\n      new String(\"none\"),\n    ];\n    for (const permittedPolicies of invalidValues) {\n      assert.throws(\n        () =>\n          xPermittedCrossDomainPolicies({\n            permittedPolicies: permittedPolicies as any,\n          }),\n        { message: /^X-Permitted-Cross-Domain-Policies does not support / },\n      );\n    }\n  });\n});\n"
  },
  {
    "path": "test/x-powered-by.test.ts",
    "content": "import { describe, it } from \"node:test\";\nimport xPoweredBy from \"../middlewares/x-powered-by\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-Powered-By middleware\", () => {\n  it(\"does nothing if the request was not set earlier in the stack\", async () => {\n    await check(xPoweredBy(), {\n      \"x-powered-by\": null,\n    });\n  });\n\n  it(\"removes the header if it was set earlier in the stack\", async () => {\n    await check(\n      (req, res, next) => {\n        res.setHeader(\"X-POWERED-BY\", \"should be destroyed\");\n        xPoweredBy()(req, res, next);\n      },\n      {\n        \"x-powered-by\": null,\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/x-xss-protection.test.ts",
    "content": "import { describe, it } from \"node:test\";\nimport xXssProtection from \"../middlewares/x-xss-protection\";\nimport { check } from \"./helpers\";\n\ndescribe(\"X-XSS-Protection middleware\", () => {\n  it('sets \"X-XSS-Protection: 0\"', async () => {\n    await check(xXssProtection(), {\n      \"x-xss-protection\": \"0\",\n    });\n  });\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitReturns\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"noUncheckedSideEffectImports\": true,\n    \"strict\": true,\n    \"target\": \"es2022\",\n    \"outDir\": \".\"\n  },\n  \"exclude\": [\"node_modules\", \"test/project-setups\"]\n}\n"
  }
]