[
  {
    "path": ".git-blame-ignore-revs",
    "content": "# style: prettier\n833e2127a843ed33f9da1b945e28933afe25a5aa\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\"on\":\n  push:\n    branches:\n      - master\n      - next\n      - beta\n      - \"*.x\"\npermissions:\n  contents: read # for checkout\njobs:\n  release:\n    permissions:\n      contents: write # to be able to publish a GitHub release\n      issues: write # to be able to comment on released issues\n      pull-requests: write # to be able to comment on released pull requests\n      id-token: write # to enable use of OIDC for npm provenance\n    name: release\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          cache: npm\n          node-version: lts/*\n      - run: npm clean-install\n      - run: corepack npm audit signatures\n      - run: npx semantic-release\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_BOT_NPM_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\"on\":\n  push:\n    branches:\n      - master\n      - renovate/**\n  pull_request:\n    types:\n      - opened\n      - synchronize\n\npermissions:\n  contents: read\n\nenv:\n  FORCE_COLOR: 1\n  NPM_CONFIG_COLOR: always\n\njobs:\n  test_matrix:\n    strategy:\n      matrix:\n        node-version:\n          - 20.8.1\n          - 22.0.0\n        os:\n          - ubuntu-latest\n    runs-on: \"${{ matrix.os }}\"\n    steps:\n      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: \"Use Node.js ${{ matrix.node-version }}\"\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version: \"${{ matrix.node-version }}\"\n          cache: npm\n      - run: npm clean-install\n      - run: corepack npm audit signatures\n      - run: npm test\n\n  test_dev:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n      - name: \"Use development Node.js version\"\n        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0\n        with:\n          node-version-file: .nvmrc\n          cache: npm\n      - run: npm clean-install\n      - run: corepack npm audit signatures\n      - run: npm test\n\n  test:\n    runs-on: ubuntu-latest\n    needs: test_matrix\n    if: ${{ !cancelled() }}\n    steps:\n      - name: All matrix versions passed\n        if: ${{ !(contains(needs.*.result, 'failure')) }}\n        run: exit 0\n      - name: Some matrix version failed\n        if: ${{ contains(needs.*.result, 'failure') }}\n        run: exit 1\n"
  },
  {
    "path": ".gitignore",
    "content": "\n# Created by https://www.gitignore.io/api/macos,windows,linux,node\n\n### Linux ###\n*~\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n### macOS ###\n*.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (http://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Typescript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n\n### Windows ###\n# Windows thumbnail cache files\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n# End of https://www.gitignore.io/api/macos,windows,linux,node"
  },
  {
    "path": ".nvmrc",
    "content": "24\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Pierre-Denis Vanduynslager\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# **release-notes-generator**\n\n[**semantic-release**](https://github.com/semantic-release/semantic-release) plugin to generate changelog content with [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog)\n\n[![Build Status](https://github.com/semantic-release/release-notes-generator/workflows/Test/badge.svg)](https://github.com/semantic-release/release-notes-generator/actions?query=workflow%3ATest+branch%3Amaster) [![npm latest version](https://img.shields.io/npm/v/@semantic-release/release-notes-generator/latest.svg)](https://www.npmjs.com/package/@semantic-release/release-notes-generator)\n[![npm next version](https://img.shields.io/npm/v/@semantic-release/release-notes-generator/next.svg)](https://www.npmjs.com/package/@semantic-release/release-notes-generator)\n\n| Step            | Description                                                                                                                                                          |\n| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `generateNotes` | Generate release notes for the commits added since the last release with [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog). |\n\n## Install\n\n> [!TIP]\n> You do not need to directly depend on this package if you are using `semantic-release`.\n> `semantic-release` already depends on this package, and defining your own direct dependency can result in conflicts when you update `semantic-release`.\n\n```bash\n$ npm install @semantic-release/release-notes-generator -D\n```\n\n## Usage\n\nThe plugin can be configured in the [**semantic-release** configuration file](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#configuration):\n\n```json\n{\n  \"plugins\": [\n    [\n      \"@semantic-release/commit-analyzer\",\n      {\n        \"preset\": \"angular\",\n        \"parserOpts\": {\n          \"noteKeywords\": [\"BREAKING CHANGE\", \"BREAKING CHANGES\", \"BREAKING\"]\n        }\n      }\n    ],\n    [\n      \"@semantic-release/release-notes-generator\",\n      {\n        \"preset\": \"angular\",\n        \"parserOpts\": {\n          \"noteKeywords\": [\"BREAKING CHANGE\", \"BREAKING CHANGES\", \"BREAKING\"]\n        },\n        \"writerOpts\": {\n          \"commitsSort\": [\"subject\", \"scope\"]\n        }\n      }\n    ]\n  ]\n}\n```\n\nWith this example:\n\n- the commits that contains `BREAKING CHANGE`, `BREAKING CHANGES` or `BREAKING` in their body will be considered breaking changes (by default the [angular preset](https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog-angular/index.js#L14) checks only for `BREAKING CHANGE` and `BREAKING CHANGES`)\n- the commits will be sorted in the changelog by `subject` then `scope` (by default the [angular preset](https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog-angular/index.js#L90) sort the commits in the changelog by `scope` then `subject`)\n\n## Configuration\n\n### Options\n\n| Option           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Default                                                                                                                                                 |\n| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `preset`         | [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) preset (possible values: [`angular`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular), [`atom`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-atom), [`codemirror`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-codemirror), [`ember`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-ember), [`eslint`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-eslint), [`express`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-express), [`jquery`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-jquery), [`jshint`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-jshint), [`conventionalcommits`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits)). | [`angular`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular)                       |\n| `config`         | NPM package name of a custom [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) preset.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | -                                                                                                                                                       |\n| `parserOpts`     | Additional [conventional-commits-parser](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-commits-parser#parseroptions) options that will extends the ones loaded by `preset` or `config`. This is convenient to use a [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) preset with some customizations without having to create a new module.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | -                                                                                                                                                       |\n| `writerOpts`     | Additional [conventional-commits-writer](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-writer#options) options that will extends the ones loaded by `preset` or `config`. This is convenient to use a [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) preset with some customizations without having to create a new module.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | -                                                                                                                                                       |\n| `host`           | The host used to generate links to issues and commits. See [conventional-changelog-writer#host](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-writer#host).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | The host from the [`repositoryurl` option](https://github.com/semantic-release/semantic-release/blob/master/docs/usage/configuration.md#repositoryurl). |\n| `linkCompare`    | Whether to include a link to compare changes since previous release in the release note.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `true`                                                                                                                                                  |\n| `linkReferences` | Whether to include a link to issues and commits in the release note. See [conventional-changelog-writer#linkreferences](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-writer#linkreferences).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | `true`                                                                                                                                                  |\n| `commit`         | Keyword used to generate commit links (formatted as `<host>/<owner>/<repository>/<commit>/<commit_sha>`). See [conventional-changelog-writer#commit](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-writer#commit).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | `commits` for Bitbucket repositories, `commit` otherwise                                                                                                |\n| `issue`          | Keyword used to generate issue links (formatted as `<host>/<owner>/<repository>/<issue>/<issue_number>`). See [conventional-changelog-writer#issue](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-writer#issue).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | `issue` for Bitbucket repositories, `issues` otherwise                                                                                                  |\n| `presetConfig`   | Additional configuration passed to the [conventional-changelog](https://github.com/conventional-changelog/conventional-changelog) preset. Used for example with [conventional-changelog-conventionalcommits](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits#specific-options).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | -                                                                                                                                                       |\n\n**Notes**: in order to use a `preset` it must be installed (for example to use the [eslint preset](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-eslint) you must install it with `npm install conventional-changelog-eslint -D`)\n\n**Note**: `config` will be overwritten by the values of `preset`. You should use either `preset` or `config`, but not both.\n\n**Note**: Individual properties of `parserOpts` and `writerOpts` will override ones loaded with an explicitly set `preset` or `config`. If `preset` or `config` are not set, only the properties set in `parserOpts` and `writerOpts` will be used.\n\n**Note**: For presets that expects a configuration object, such as [`conventionalcommits`](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-conventionalcommits), the `presetConfig` option **must** be set.\n"
  },
  {
    "path": "index.js",
    "content": "import { format } from \"url\";\nimport { find, merge } from \"lodash-es\";\nimport getStream from \"get-stream\";\nimport intoStream from \"into-stream\";\nimport { CommitParser } from \"conventional-commits-parser\";\nimport writer from \"./wrappers/conventional-changelog-writer.js\";\nimport { filterRevertedCommitsSync } from \"conventional-commits-filter\";\nimport { readPackageUp } from \"read-package-up\";\nimport debugFactory from \"debug\";\nimport loadChangelogConfig from \"./lib/load-changelog-config.js\";\nimport HOSTS_CONFIG from \"./lib/hosts-config.js\";\n\nconst debug = debugFactory(\"semantic-release:release-notes-generator\");\n\n/**\n * Generate the changelog for all the commits in `options.commits`.\n *\n * @param {Object} pluginConfig The plugin configuration.\n * @param {String} pluginConfig.preset conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint').\n * @param {String} pluginConfig.config Requireable npm package with a custom conventional-changelog preset\n * @param {Object} pluginConfig.parserOpts Additional `conventional-changelog-parser` options that will overwrite ones loaded by `preset` or `config`.\n * @param {Object} pluginConfig.writerOpts Additional `conventional-changelog-writer` options that will overwrite ones loaded by `preset` or `config`.\n * @param {Object} context The semantic-release context.\n * @param {Array<Object>} context.commits The commits to analyze.\n * @param {Object} context.lastRelease The last release with `gitHead` corresponding to the commit hash used to make the last release and `gitTag` corresponding to the git tag associated with `gitHead`.\n * @param {Object} context.nextRelease The next release with `gitHead` corresponding to the commit hash used to make the  release, the release `version` and `gitTag` corresponding to the git tag associated with `gitHead`.\n * @param {Object} context.options.repositoryUrl The git repository URL.\n *\n * @returns {String} The changelog for all the commits in `context.commits`.\n */\nexport async function generateNotes(pluginConfig, context) {\n  const { commits, lastRelease, nextRelease, options, cwd } = context;\n  const repositoryUrl = options.repositoryUrl.replace(/\\.git$/i, \"\");\n  const { commitOpts, parserOpts, writerOpts } = await loadChangelogConfig(pluginConfig, context);\n\n  const [match, auth, host, path] = /^(?!.+:\\/\\/)(?:(?<auth>.*)@)?(?<host>.*?):(?<path>.*)$/.exec(repositoryUrl) || [];\n  let { hostname, port, pathname, protocol } = new URL(\n    match ? `ssh://${auth ? `${auth}@` : \"\"}${host}/${path}` : repositoryUrl\n  );\n  port = protocol.includes(\"ssh\") ? \"\" : port;\n  protocol = protocol && /http[^s]/.test(protocol) ? \"http\" : \"https\";\n  const [, owner, repository] = /^\\/(?<owner>[^/]+)?\\/?(?<repository>.+)?$/.exec(pathname) || [];\n\n  const { issue, commit, referenceActions, issuePrefixes } =\n    find(HOSTS_CONFIG, (conf) => conf.hostname === hostname) || HOSTS_CONFIG.default;\n  const parser = new CommitParser({ referenceActions, issuePrefixes, ...parserOpts });\n  const parsedCommits = filterRevertedCommitsSync(\n    commits\n      .filter(({ message, hash }) => {\n        if (!message.trim()) {\n          debug(\"Skip commit %s with empty message\", hash);\n          return false;\n        }\n\n        if (commitOpts && commitOpts.ignore && new RegExp(commitOpts.ignore).test(message) && !commitOpts.merges) {\n          debug(\"Skip commit %s by ignore option\", hash);\n          return false;\n        }\n\n        return true;\n      })\n      .map((rawCommit) => ({\n        ...rawCommit,\n        ...parser.parse(rawCommit.message),\n      }))\n  );\n  const previousTag = lastRelease.gitTag || lastRelease.gitHead;\n  const currentTag = nextRelease.gitTag || nextRelease.gitHead;\n  const { host: hostConfig, linkCompare, linkReferences, commit: commitConfig, issue: issueConfig } = pluginConfig;\n  const changelogContext = merge(\n    {\n      version: nextRelease.version,\n      host: format({ protocol, hostname, port }),\n      owner,\n      repository,\n      previousTag,\n      currentTag,\n      linkCompare: currentTag && previousTag,\n      issue,\n      commit,\n      packageData: ((await readPackageUp({ normalize: false, cwd })) || {}).packageJson,\n    },\n    { host: hostConfig, linkCompare, linkReferences, commit: commitConfig, issue: issueConfig }\n  );\n\n  debug(\"version: %o\", changelogContext.version);\n  debug(\"host: %o\", changelogContext.hostname);\n  debug(\"owner: %o\", changelogContext.owner);\n  debug(\"repository: %o\", changelogContext.repository);\n  debug(\"previousTag: %o\", changelogContext.previousTag);\n  debug(\"currentTag: %o\", changelogContext.currentTag);\n  debug(\"host: %o\", changelogContext.host);\n  debug(\"linkReferences: %o\", changelogContext.linkReferences);\n  debug(\"issue: %o\", changelogContext.issue);\n  debug(\"commit: %o\", changelogContext.commit);\n\n  return getStream(intoStream.object(parsedCommits).pipe(writer(changelogContext, writerOpts)));\n}\n"
  },
  {
    "path": "lib/hosts-config.js",
    "content": "export default {\n  github: {\n    hostname: \"github.com\",\n    issue: \"issues\",\n    commit: \"commit\",\n    referenceActions: [\"close\", \"closes\", \"closed\", \"fix\", \"fixes\", \"fixed\", \"resolve\", \"resolves\", \"resolved\"],\n    issuePrefixes: [\"#\", \"gh-\"],\n  },\n  bitbucket: {\n    hostname: \"bitbucket.org\",\n    issue: \"issue\",\n    commit: \"commits\",\n    referenceActions: [\n      \"close\",\n      \"closes\",\n      \"closed\",\n      \"closing\",\n      \"fix\",\n      \"fixes\",\n      \"fixed\",\n      \"fixing\",\n      \"resolve\",\n      \"resolves\",\n      \"resolved\",\n      \"resolving\",\n    ],\n    issuePrefixes: [\"#\"],\n  },\n  gitlab: {\n    hostname: \"gitlab.com\",\n    issue: \"issues\",\n    commit: \"commit\",\n    referenceActions: [\"close\", \"closes\", \"closed\", \"closing\", \"fix\", \"fixes\", \"fixed\", \"fixing\"],\n    issuePrefixes: [\"#\"],\n  },\n  default: {\n    issue: \"issues\",\n    commit: \"commit\",\n    referenceActions: [\n      \"close\",\n      \"closes\",\n      \"closed\",\n      \"closing\",\n      \"fix\",\n      \"fixes\",\n      \"fixed\",\n      \"fixing\",\n      \"resolve\",\n      \"resolves\",\n      \"resolved\",\n      \"resolving\",\n    ],\n    issuePrefixes: [\"#\", \"gh-\"],\n  },\n};\n"
  },
  {
    "path": "lib/load-changelog-config.js",
    "content": "import { dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport importFrom from \"import-from-esm\";\nimport conventionalChangelogAngular from \"conventional-changelog-angular\";\n\n/**\n * Load `conventional-changelog-parser` options. Handle presets that return either a `Promise<Array>` or a `Promise<Function>`.\n *\n * @param {Object} pluginConfig The plugin configuration.\n * @param {Object} pluginConfig.preset conventional-changelog preset ('angular', 'atom', 'codemirror', 'ember', 'eslint', 'express', 'jquery', 'jscs', 'jshint')\n * @param {string} pluginConfig.config Requireable npm package with a custom conventional-changelog preset\n * @param {Object} pluginConfig.parserOpts Additional `conventional-changelog-parser` options that will overwrite ones loaded by `preset` or `config`.\n * @param {Object} pluginConfig.writerOpts Additional `conventional-changelog-writer` options that will overwrite ones loaded by `preset` or `config`.\n * @param {Object} context The semantic-release context.\n * @param {Array<Object>} context.commits The commits to analyze.\n * @param {String} context.cwd The current working directory.\n *\n * @return {Promise<Object>} a `Promise` that resolve to the `conventional-changelog-core` config.\n */\nexport default async ({ preset, config, parserOpts, writerOpts, presetConfig }, { cwd }) => {\n  let loadedConfig;\n  const __dirname = dirname(fileURLToPath(import.meta.url));\n\n  if (preset) {\n    const presetPackage = `conventional-changelog-${preset.toLowerCase()}`;\n    loadedConfig = await (\n      (await importFrom.silent(__dirname, presetPackage)) || (await importFrom(cwd, presetPackage))\n    )(presetConfig);\n  } else if (config) {\n    loadedConfig = await ((await importFrom.silent(__dirname, config)) || (await importFrom(cwd, config)))();\n  } else {\n    loadedConfig = await conventionalChangelogAngular();\n  }\n\n  return {\n    commitOpts: loadedConfig.commits,\n    parserOpts: { ...loadedConfig.parser, ...parserOpts },\n    writerOpts: { ...loadedConfig.writer, ...writerOpts },\n  };\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@semantic-release/release-notes-generator\",\n  \"description\": \"semantic-release plugin to generate changelog content with conventional-changelog\",\n  \"version\": \"0.0.0-development\",\n  \"author\": \"Pierre Vanduynslager (https://twitter.com/@pvdlg_)\",\n  \"bugs\": {\n    \"url\": \"https://github.com/semantic-release/release-notes-generator/issues\"\n  },\n  \"contributors\": [\n    \"Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)\",\n    \"Gregor Martynus (https://twitter.com/gr2m)\"\n  ],\n  \"dependencies\": {\n    \"conventional-changelog-angular\": \"^8.0.0\",\n    \"conventional-changelog-writer\": \"^8.0.0\",\n    \"conventional-commits-filter\": \"^5.0.0\",\n    \"conventional-commits-parser\": \"^6.0.0\",\n    \"debug\": \"^4.0.0\",\n    \"get-stream\": \"^7.0.0\",\n    \"import-from-esm\": \"^2.0.0\",\n    \"into-stream\": \"^7.0.0\",\n    \"lodash-es\": \"^4.17.21\",\n    \"read-package-up\": \"^11.0.0\"\n  },\n  \"devDependencies\": {\n    \"ava\": \"6.4.1\",\n    \"c8\": \"11.0.0\",\n    \"conventional-changelog-atom\": \"5.1.0\",\n    \"conventional-changelog-conventionalcommits\": \"9.3.1\",\n    \"conventional-changelog-ember\": \"5.1.0\",\n    \"conventional-changelog-eslint\": \"6.1.0\",\n    \"conventional-changelog-express\": \"5.1.0\",\n    \"conventional-changelog-jshint\": \"5.2.0\",\n    \"escape-string-regexp\": \"5.0.0\",\n    \"fs-extra\": \"11.3.4\",\n    \"lockfile-lint\": \"5.0.0\",\n    \"ls-engines\": \"0.9.4\",\n    \"npm-run-all2\": \"8.0.4\",\n    \"prettier\": \"3.8.3\",\n    \"publint\": \"0.3.18\",\n    \"semantic-release\": \"25.0.3\",\n    \"sinon\": \"21.1.2\",\n    \"stream-buffers\": \"3.0.3\",\n    \"tempy\": \"3.2.0\",\n    \"testdouble\": \"3.20.2\"\n  },\n  \"engines\": {\n    \"node\": \">=20.8.1\"\n  },\n  \"files\": [\n    \"lib\",\n    \"wrappers\",\n    \"index.js\"\n  ],\n  \"homepage\": \"https://github.com/semantic-release/release-notes-generator#readme\",\n  \"keywords\": [\n    \"changelog\",\n    \"conventional-changelog\",\n    \"conventional-commits\",\n    \"github\",\n    \"publish\",\n    \"release\",\n    \"release-note-generator\",\n    \"semantic-release\"\n  ],\n  \"license\": \"MIT\",\n  \"main\": \"./index.js\",\n  \"exports\": \"./index.js\",\n  \"c8\": {\n    \"include\": [\n      \"lib/**/*.js\",\n      \"index.js\"\n    ],\n    \"reporter\": [\n      \"json\",\n      \"text\",\n      \"html\"\n    ],\n    \"all\": true\n  },\n  \"peerDependencies\": {\n    \"semantic-release\": \">=20.1.0\"\n  },\n  \"lockfile-lint\": {\n    \"path\": \"package-lock.json\",\n    \"type\": \"npm\",\n    \"validate-https\": true,\n    \"allowed-hosts\": [\n      \"npm\"\n    ]\n  },\n  \"prettier\": {\n    \"printWidth\": 120,\n    \"trailingComma\": \"es5\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\",\n    \"provenance\": true\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/semantic-release/release-notes-generator.git\"\n  },\n  \"scripts\": {\n    \"lint:prettier\": \"prettier --check \\\"{lib,test}/**/*.{js,json,ts}\\\" \\\"*.{md,json,js}\\\" \\\".github/**/*.yml\\\"\",\n    \"lint:prettier:fix\": \"prettier --write \\\"*.{js,json,md}\\\" \\\".github/**/*.{md,yml}\\\" \\\"{bin,lib,test}/**/*.js\\\"\",\n    \"lint:lockfile\": \"lockfile-lint\",\n    \"lint:engines\": \"ls-engines\",\n    \"lint:publish\": \"publint --strict\",\n    \"test\": \"npm-run-all --print-label --parallel lint:* --parallel test:*\",\n    \"test:unit\": \"c8 ava --verbose\",\n    \"test:integration\": \"ava --verbose test/integration.test.js\"\n  },\n  \"type\": \"module\",\n  \"ava\": {\n    \"files\": [\n      \"test/**/*.test.js\",\n      \"!test/integration.test.js\"\n    ],\n    \"nodeArguments\": [\n      \"--loader=testdouble\",\n      \"--no-warnings\"\n    ]\n  },\n  \"renovate\": {\n    \"extends\": [\n      \"github>semantic-release/.github:renovate-config\"\n    ]\n  },\n  \"packageManager\": \"npm@11.12.1\"\n}\n"
  },
  {
    "path": "test/integration.test.js",
    "content": "import path from \"node:path\";\nimport test from \"ava\";\nimport fs from \"fs-extra\";\nimport escape from \"escape-string-regexp\";\nimport { temporaryDirectory } from \"tempy\";\nimport * as td from \"testdouble\";\nimport streamBuffers from \"stream-buffers\";\nimport conventionalChangelogEslint from \"conventional-changelog-eslint\";\n\nconst cwd = process.cwd();\nconst host = \"https://github.com\";\nconst owner = \"owner\";\nconst repository = \"repo\";\nconst repositoryUrl = `${host}/${owner}/${repository}`;\nconst lastRelease = { gitTag: \"v1.0.0\" };\nconst nextRelease = { gitTag: \"v2.0.0\", version: \"2.0.0\" };\n\ntest.afterEach.always(() => {\n  td.reset();\n});\n\ntest.serial('Use \"conventional-changelog-angular\" by default', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes({}, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits });\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](https://github.com/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://github.com/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Set conventional-changelog-writer context\", async (t) => {\n  t.plan(0);\n  const cwd = temporaryDirectory();\n  const writerDouble = td.func();\n  td.when(\n    writerDouble({\n      version: nextRelease.version,\n      host,\n      owner,\n      repository,\n      previousTag: lastRelease.gitTag,\n      currentTag: nextRelease.gitTag,\n      linkCompare: lastRelease.gitTag,\n      issue: \"issues\",\n      commit: \"commit\",\n      packageData: undefined,\n      linkReferences: undefined,\n    }),\n    { ignoreExtraArgs: true }\n  ).thenReturn(new streamBuffers.WritableStreamBuffer());\n  await td.replaceEsm(\"../wrappers/conventional-changelog-writer.js\", {}, writerDouble);\n  const { generateNotes } = await import(\"../index.js\");\n\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  await generateNotes({}, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits });\n});\n\ntest.serial(\"Set conventional-changelog-writer context with package.json\", async (t) => {\n  t.plan(0);\n  const cwd = temporaryDirectory();\n  const packageData = { name: \"package\", version: \"0.0.0\" };\n  const writerDouble = td.func();\n  td.when(\n    writerDouble({\n      version: nextRelease.version,\n      host,\n      owner,\n      repository,\n      previousTag: lastRelease.gitTag,\n      currentTag: nextRelease.gitTag,\n      linkCompare: lastRelease.gitTag,\n      issue: \"issues\",\n      commit: \"commit\",\n      packageData,\n      linkReferences: undefined,\n    }),\n    { ignoreExtraArgs: true }\n  ).thenReturn(new streamBuffers.WritableStreamBuffer());\n  await td.replaceEsm(\"../wrappers/conventional-changelog-writer.js\", {}, writerDouble);\n  const { generateNotes } = await import(\"../index.js\");\n\n  await fs.outputJson(path.resolve(cwd, \"package.json\"), packageData);\n\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  await generateNotes({}, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits });\n});\n\ntest.serial('Accept a \"preset\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"Fix: First fix (fixes #123)\" },\n    { hash: \"222\", message: \"Update: Second feature (fixes #456)\" },\n  ];\n  const changelog = await generateNotes(\n    { preset: \"eslint\" },\n    { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Fix/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* First fix (fixes #123) ([111](https://github.com/owner/repo/commit/111)), closes [#123](https://github.com/owner/repo/issues/123)\"\n      )\n    )\n  );\n  t.regex(changelog, /### Update/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* Second feature (fixes #456) ([222](https://github.com/owner/repo/commit/222)), closes [#456](https://github.com/owner/repo/issues/456)\"\n      )\n    )\n  );\n});\n\ntest.serial('Accept a \"config\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"Fix: First fix (fixes #123)\" },\n    { hash: \"222\", message: \"Update: Second feature (fixes #456)\" },\n  ];\n  const changelog = await generateNotes(\n    { config: \"conventional-changelog-eslint\" },\n    { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Fix/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* First fix (fixes #123) ([111](https://github.com/owner/repo/commit/111)), closes [#123](https://github.com/owner/repo/issues/123)\"\n      )\n    )\n  );\n  t.regex(changelog, /### Update/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* Second feature (fixes #456) ([222](https://github.com/owner/repo/commit/222)), closes [#456](https://github.com/owner/repo/issues/456)\"\n      )\n    )\n  );\n});\n\ntest.serial('Accept a \"parseOpts\" and \"writerOpts\" objects as option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"%%Fix%% First fix (keyword #123)\" },\n    { hash: \"222\", message: \"%%Update%% Second feature (keyword JIRA-456)\" },\n  ];\n  const changelog = await generateNotes(\n    {\n      parserOpts: {\n        headerPattern: /^%%(?<tag>.*?)%% (?<message>.*)$/,\n        headerCorrespondence: [\"tag\", \"message\"],\n        referenceActions: [\"keyword\"],\n        issuePrefixes: [\"#\", \"JIRA-\"],\n      },\n      writerOpts: (await conventionalChangelogEslint()).writer,\n    },\n    { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Fix/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* First fix (keyword #123) ([111](https://github.com/owner/repo/commit/111)), closes [#123](https://github.com/owner/repo/issues/123)\"\n      )\n    )\n  );\n  t.regex(changelog, /### Update/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* Second feature (keyword JIRA-456) ([222](https://github.com/owner/repo/commit/222)), closes [#456](https://github.com/owner/repo/issues/456)\"\n      )\n    )\n  );\n});\n\ntest.serial('Accept a partial \"parseOpts\" and \"writerOpts\" objects as option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): 2 First fix (fixes #123)\" },\n    { hash: \"222\", message: \"fix(scope2): 1 Second fix (fixes #456)\" },\n  ];\n  const changelog = await generateNotes(\n    {\n      preset: \"angular\",\n      parserOpts: { headerPattern: /^(?<type>\\w*)\\((?<scope>.*)\\): (?<subject>.*)$/ },\n      writerOpts: { commitsSort: [\"subject\", \"scope\"] },\n    },\n    { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, /\\* \\*\\*scope2:\\*\\* 1 Second fix[\\S\\s]*\\* \\*\\*scope1:\\*\\* 2 First fix/);\n});\n\ntest.serial('Accept a partial \"presetConfig\" object as option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix: First fix\" },\n    { hash: \"222\", message: \"test: Change test\" },\n  ];\n  const changelog = await generateNotes(\n    {\n      preset: \"conventionalcommits\",\n      presetConfig: {\n        types: [\n          { type: \"fix\", section: \"Bug Fixes\", hidden: true },\n          { type: \"test\", section: \"Test !!\", hidden: false },\n        ],\n      },\n    },\n    { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n  );\n\n  t.notRegex(changelog, /### Bug Fixes/);\n  t.notRegex(changelog, new RegExp(escape(\"First fix\")));\n  t.regex(changelog, /### Test !!/);\n  t.regex(changelog, new RegExp(escape(\"* Change test ([222](https://github.com/owner/repo/commit/222))\")));\n});\n\ntest.serial('Accept ignoreCommits in \"presetConfig\" object as option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix: First fix\" },\n    { hash: \"222\", message: \"test: Change test [python]\" },\n  ];\n  const changelog = await generateNotes(\n    {\n      preset: \"conventionalcommits\",\n      presetConfig: {\n        ignoreCommits: \"\\\\[python\\\\]\",\n        types: [\n          { type: \"fix\", section: \"Bug Fixes\", hidden: false },\n          { type: \"test\", section: \"Test !!\", hidden: false },\n        ],\n      },\n    },\n    { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"First fix\")));\n  t.notRegex(changelog, /### Test !!/);\n  t.notRegex(changelog, new RegExp(escape(\"* Change test ([222](https://github.com/owner/repo/commit/222))\")));\n});\n\ntest.serial('Use \"gitHead\" from \"lastRelease\" and \"nextRelease\" if \"gitTag\" is not defined', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    {\n      cwd,\n      options: { repositoryUrl },\n      lastRelease: { gitHead: \"abc\" },\n      nextRelease: { gitHead: \"def\", version: \"2.0.0\" },\n      commits,\n    }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/abc...def)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](https://github.com/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://github.com/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a custom repository URL\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"http://domain.com:90/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(http://domain.com:90/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](http://domain.com:90/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](http://domain.com:90/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a custom repository URL with git format\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"git@domain.com:owner/repo.git\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://domain.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](https://domain.com/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://domain.com/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a custom repository URL with git format without user\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"domain.com:owner/repo.git\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://domain.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](https://domain.com/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://domain.com/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a custom repository URL with git+http format\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"git+http://domain.com:90/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(http://domain.com:90/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](http://domain.com:90/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](http://domain.com:90/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial('Accept a custom repository URL with \".git\" extension', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"https://domain.com:90/owner/repo.git\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://domain.com:90/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope1:** First fix ([111](https://domain.com:90/owner/repo/commit/111))\"))\n  );\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://domain.com:90/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a custom repository URL with git+https format\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\\n\\nresolve #10\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"git+https://domain.com:90/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://domain.com:90/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* **scope1:** First fix ([111](https://domain.com:90/owner/repo/commit/111)), closes [#10](https://domain.com:90/owner/repo/issues/10)\"\n      )\n    )\n  );\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://domain.com:90/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a custom repository URL with git+ssh format and custom port\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    {\n      cwd,\n      options: { repositoryUrl: \"git+ssh://git@domain.com:2222/owner/repo.git\" },\n      lastRelease,\n      nextRelease,\n      commits,\n    }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://domain.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](https://domain.com/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://domain.com/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial(\"Accept a Bitbucket repository URL\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\\n\\nResolves #10\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"git+https://bitbucket.org/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://bitbucket.org/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* **scope1:** First fix ([111](https://bitbucket.org/owner/repo/commits/111)), closes [#10](https://bitbucket.org/owner/repo/issue/10)\"\n      )\n    )\n  );\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://bitbucket.org/owner/repo/commits/222))\"))\n  );\n});\n\ntest.serial(\"Accept a Gitlab repository URL\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\\n\\nclosed #10\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    { cwd, options: { repositoryUrl: \"git+https://gitlab.com/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://gitlab.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* **scope1:** First fix ([111](https://gitlab.com/owner/repo/commit/111)), closes [#10](https://gitlab.com/owner/repo/issues/10)\"\n      )\n    )\n  );\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://gitlab.com/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial('Accept a \"linkCompare\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\\n\\nResolves #10\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    { linkCompare: false },\n    { cwd, options: { repositoryUrl: \"git+https://bitbucket.org/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"# 2.0.0\")));\n  t.notRegex(changelog, new RegExp(escape(\"(https://bitbucket.org/owner/repo/compare/v1.0.0...v2.0.0)\")));\n});\n\ntest.serial('Accept a \"linkReferences\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\\n\\nResolves #10\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    { linkReferences: false },\n    { cwd, options: { repositoryUrl: \"git+https://bitbucket.org/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix 111, closes #10\")));\n  t.regex(changelog, /### Features/);\n  t.regex(changelog, new RegExp(escape(\"* **scope2:** Second feature 222\")));\n});\n\ntest.serial('Accept a \"host\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    { host: \"http://my-host:90\" },\n    { cwd, options: { repositoryUrl: \"https://github.com/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(http://my-host:90/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](http://my-host:90/owner/repo/commit/111))\")));\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](http://my-host:90/owner/repo/commit/222))\"))\n  );\n});\n\ntest.serial('Accept a \"commit\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    { commit: \"test-commits\" },\n    { cwd, options: { repositoryUrl: \"https://github.com/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope1:** First fix ([111](https://github.com/owner/repo/test-commits/111))\"))\n  );\n  t.regex(changelog, /### Features/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope2:** Second feature ([222](https://github.com/owner/repo/test-commits/222))\"))\n  );\n});\n\ntest.serial('Accept an \"issue\" option', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [{ hash: \"111\", message: \"fix(scope1): First fix\\n\\nresolve #10\" }];\n  const changelog = await generateNotes(\n    { issue: \"test-issues\" },\n    { cwd, options: { repositoryUrl: \"https://github.com/owner/repo\" }, lastRelease, nextRelease, commits }\n  );\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(\n      escape(\n        \"* **scope1:** First fix ([111](https://github.com/owner/repo/commit/111)), closes [#10](https://github.com/owner/repo/test-issues/10)\"\n      )\n    )\n  );\n});\n\ntest.serial(\"Ignore malformatted commits and include valid ones\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"Feature => Invalid message\" },\n  ];\n  const changelog = await generateNotes({}, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits });\n\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, /\\* \\*\\*scope1:\\*\\* First fix/);\n  t.notRegex(changelog, /### Features/);\n  t.notRegex(changelog, /Feature => Invalid message/);\n});\n\ntest.serial(\"Exclude commits if they have a matching revert commits\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"df012f1\", message: \"revert: feat(scope2): First feature\\n\\nThis reverts commit df012f2.\\n\" },\n    { hash: \"df012f2\", message: \"feat(scope2): First feature\" },\n    { hash: \"df012f3\", message: \"fix(scope1): First fix\" },\n  ];\n  const changelog = await generateNotes({}, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits });\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(\n    changelog,\n    new RegExp(escape(\"* **scope1:** First fix ([df012f3](https://github.com/owner/repo/commit/df012f3))\"))\n  );\n  t.notRegex(changelog, /### Features/);\n  t.notRegex(changelog, /Second feature/);\n});\n\ntest.serial(\"Exclude commits with empty message\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"\" },\n    { hash: \"333\", message: \"  \" },\n  ];\n  const changelog = await generateNotes({}, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits });\n\n  t.regex(changelog, new RegExp(escape(\"(https://github.com/owner/repo/compare/v1.0.0...v2.0.0)\")));\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix ([111](https://github.com/owner/repo/commit/111))\")));\n  t.notRegex(changelog, /222/);\n  t.notRegex(changelog, /333/);\n});\n\ntest.serial('Throw error if \"preset\" doesn`t exist', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"Fix: First fix (fixes #123)\" },\n    { hash: \"222\", message: \"Update: Second feature (fixes #456)\" },\n  ];\n  await t.throwsAsync(\n    generateNotes({ preset: \"unknown-preset\" }, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }),\n    { code: \"MODULE_NOT_FOUND\" }\n  );\n});\n\ntest.serial('Throw error if \"config\" doesn`t exist', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"Fix: First fix (fixes #123)\" },\n    { hash: \"222\", message: \"Update: Second feature (fixes #456)\" },\n  ];\n  await t.throwsAsync(\n    generateNotes({ config: \"unknown-config\" }, { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }),\n    { code: \"MODULE_NOT_FOUND\" }\n  );\n});\n\ntest.serial('ReThrow error from \"conventional-changelog\"', async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"Fix: First fix (fixes #123)\" },\n    { hash: \"222\", message: \"Update: Second feature (fixes #456)\" },\n  ];\n\n  await t.throwsAsync(\n    generateNotes(\n      {\n        writerOpts: {\n          transform() {\n            throw new Error(\"Test error\");\n          },\n        },\n      },\n      { cwd, options: { repositoryUrl }, lastRelease, nextRelease, commits }\n    ),\n    { message: \"Test error\" }\n  );\n});\n\ntest(\"Accept a custom AWS CodeCommit repository URL\", async (t) => {\n  const { generateNotes } = await import(\"../index.js\");\n  const commits = [\n    { hash: \"111\", message: \"fix(scope1): First fix\" },\n    { hash: \"222\", message: \"feat(scope2): Second feature\" },\n  ];\n  const changelog = await generateNotes(\n    {},\n    {\n      cwd,\n      options: {\n        repositoryUrl: \"codecommit::eu-central-1://profile@repository-name\",\n      },\n      lastRelease,\n      nextRelease,\n      commits,\n    }\n  );\n\n  t.regex(changelog, /### Bug Fixes/);\n  t.regex(changelog, new RegExp(escape(\"* **scope1:** First fix 111\")));\n  t.regex(changelog, /### Features/);\n  t.regex(changelog, new RegExp(escape(\"* **scope2:** Second feature 222\")));\n});\n"
  },
  {
    "path": "test/load-changelog-config.test.js",
    "content": "import test from \"ava\";\nimport importFrom from \"import-from-esm\";\nimport sinon from \"sinon\";\n\nimport conventionalChangelogAngular from \"conventional-changelog-angular\";\nimport loadChangelogConfig from \"../lib/load-changelog-config.js\";\n\nconst cwd = process.cwd();\n\n/**\n * assertion to compare loaded writerOpts with the expected writerOpts from the angular preset\n *\n * @param {Object} t AVA assertion library.\n * @param {Object} loadedWriterOpts\n * @param {Object} angularPresetWriterOpts\n */\nfunction assertWriterOptsAreFromAngularPreset(t, loadedWriterOpts, angularPresetWriterOpts) {\n  const { transform: loadedTransform, ...loadedWriterOptsWithoutTransform } = loadedWriterOpts;\n  const { transform: angularPresetTransform, ...angularPresetWriterOptsWithoutTransform } = angularPresetWriterOpts;\n\n  t.deepEqual(loadedWriterOptsWithoutTransform, angularPresetWriterOptsWithoutTransform);\n  t.is(loadedTransform.toString(), angularPresetTransform.toString());\n}\n\n/**\n * AVA macro to verify that `loadChangelogConfig` return a config object with parserOpts and writerOpts.\n *\n * @method loadPreset\n * @param {Object} t AVA assertion library.\n * @param {String} preset the `conventional-changelog` preset to test.\n * @param {Object} pluginOptions The plugin configuration.\n */\nasync function loadPreset(t, preset, pluginOptions) {\n  const changelogConfig = await loadChangelogConfig({ ...pluginOptions, preset }, { cwd });\n\n  t.truthy(changelogConfig.parserOpts.headerPattern);\n  t.truthy(changelogConfig.writerOpts.groupBy);\n}\n\nloadPreset.title = (providedTitle, preset) => `${providedTitle} Load \"${preset}\" preset`.trim();\n\n/**\n * AVA macro to verify that `loadChangelogConfig` return a config object with parserOpts and writerOpts.\n *\n * @method loadPreset\n * @param {Object} t AVA assertion library.\n * @param {String} config the `conventional-changelog` config to test.\n * @param {Object} pluginOptions The plugin configuration.\n */\nasync function loadConfig(t, config, pluginOptions) {\n  const changelogConfig = await loadChangelogConfig(\n    { ...pluginOptions, config: `conventional-changelog-${config}` },\n    { cwd }\n  );\n\n  t.truthy(changelogConfig.parserOpts.headerPattern);\n  t.truthy(changelogConfig.writerOpts.groupBy);\n}\n\nloadConfig.title = (providedTitle, config) => `${providedTitle} Load \"${config}\" config`.trim();\n\ntest('Load \"conventional-changelog-angular\" by default', async (t) => {\n  const changelogConfig = await loadChangelogConfig({}, { cwd });\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.deepEqual(changelogConfig.parserOpts, angularChangelogConfig.parser);\n  assertWriterOptsAreFromAngularPreset(t, changelogConfig.writerOpts, angularChangelogConfig.writer);\n});\n\ntest('Accept a \"parserOpts\" object as option', async (t) => {\n  const customParserOptions = {\n    headerPattern: /^##(?<tag>.*?)## (?<shortDesc>.*)$/,\n    headerCorrespondence: [\"tag\", \"shortDesc\"],\n  };\n  const changelogConfig = await loadChangelogConfig({ parserOpts: customParserOptions }, { cwd });\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.is(customParserOptions.headerPattern, changelogConfig.parserOpts.headerPattern);\n  t.deepEqual(customParserOptions.headerCorrespondence, changelogConfig.parserOpts.headerCorrespondence);\n  t.deepEqual(changelogConfig.parserOpts.noteKeywords, angularChangelogConfig.parser.noteKeywords);\n  assertWriterOptsAreFromAngularPreset(t, changelogConfig.writerOpts, angularChangelogConfig.writer);\n});\n\ntest('Accept a \"writerOpts\" object as option', async (t) => {\n  const customWriterOptions = { commitGroupsSort: \"title\", commitsSort: [\"scope\", \"subject\"] };\n  const changelogConfig = await loadChangelogConfig({ writerOpts: customWriterOptions }, { cwd });\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.is(customWriterOptions.commitGroupsSort, changelogConfig.writerOpts.commitGroupsSort);\n  t.deepEqual(customWriterOptions.commitsSort, changelogConfig.writerOpts.commitsSort);\n  t.deepEqual(changelogConfig.writerOpts.noteGroupsSort, angularChangelogConfig.writer.noteGroupsSort);\n  t.deepEqual(changelogConfig.parserOpts, angularChangelogConfig.parser);\n});\n\ntest('Accept a partial \"parserOpts\" object as option that overwrite a preset', async (t) => {\n  const customParserOptions = {\n    headerPattern: /^##(?<tag>.*?)## (?<shortDesc>.*)$/,\n    headerCorrespondence: [\"tag\", \"shortDesc\"],\n  };\n  const changelogConfig = await loadChangelogConfig({ parserOpts: customParserOptions, preset: \"angular\" }, { cwd });\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.is(customParserOptions.headerPattern, changelogConfig.parserOpts.headerPattern);\n  t.deepEqual(customParserOptions.headerCorrespondence, changelogConfig.parserOpts.headerCorrespondence);\n  t.truthy(changelogConfig.parserOpts.noteKeywords);\n  assertWriterOptsAreFromAngularPreset(t, changelogConfig.writerOpts, angularChangelogConfig.writer);\n});\n\ntest('Accept a \"writerOpts\" object as option that overwrite a preset', async (t) => {\n  const customWriterOptions = { commitGroupsSort: \"title\", commitsSort: [\"scope\", \"subject\"] };\n  const changelogConfig = await loadChangelogConfig({ writerOpts: customWriterOptions, preset: \"angular\" }, { cwd });\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.is(customWriterOptions.commitGroupsSort, changelogConfig.writerOpts.commitGroupsSort);\n  t.deepEqual(customWriterOptions.commitsSort, changelogConfig.writerOpts.commitsSort);\n  t.truthy(changelogConfig.writerOpts.noteGroupsSort);\n  t.deepEqual(changelogConfig.parserOpts, angularChangelogConfig.parser);\n});\n\ntest('Accept a partial \"parserOpts\" object as option that overwrite a config', async (t) => {\n  const customParserOptions = {\n    headerPattern: /^##(?<tag>.*?)## (?<shortDesc>.*)$/,\n    headerCorrespondence: [\"tag\", \"shortDesc\"],\n  };\n  const changelogConfig = await loadChangelogConfig(\n    {\n      parserOpts: customParserOptions,\n      config: \"conventional-changelog-angular\",\n    },\n    { cwd }\n  );\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.is(customParserOptions.headerPattern, changelogConfig.parserOpts.headerPattern);\n  t.deepEqual(customParserOptions.headerCorrespondence, changelogConfig.parserOpts.headerCorrespondence);\n  t.truthy(changelogConfig.parserOpts.noteKeywords);\n  assertWriterOptsAreFromAngularPreset(t, changelogConfig.writerOpts, angularChangelogConfig.writer);\n});\n\ntest('Accept a \"writerOpts\" object as option that overwrite a config', async (t) => {\n  const customWriterOptions = { commitGroupsSort: \"title\", commitsSort: [\"scope\", \"subject\"] };\n  const changelogConfig = await loadChangelogConfig(\n    {\n      writerOpts: customWriterOptions,\n      config: \"conventional-changelog-angular\",\n    },\n    { cwd }\n  );\n  const angularChangelogConfig = await conventionalChangelogAngular();\n\n  t.is(customWriterOptions.commitGroupsSort, changelogConfig.writerOpts.commitGroupsSort);\n  t.deepEqual(customWriterOptions.commitsSort, changelogConfig.writerOpts.commitsSort);\n  t.truthy(changelogConfig.writerOpts.noteGroupsSort);\n  t.deepEqual(changelogConfig.parserOpts, angularChangelogConfig.parser);\n});\n\ntest(loadPreset, \"angular\");\ntest(loadConfig, \"angular\");\ntest(loadPreset, \"atom\");\ntest(loadConfig, \"atom\");\ntest(loadPreset, \"ember\");\ntest(loadConfig, \"ember\");\ntest(loadPreset, \"eslint\");\ntest(loadConfig, \"eslint\");\ntest(loadPreset, \"express\");\ntest(loadConfig, \"express\");\ntest(loadPreset, \"jshint\");\ntest(loadConfig, \"jshint\");\ntest(loadPreset, \"conventionalcommits\", { presetConfig: {} });\ntest(loadConfig, \"conventionalcommits\", { presetConfig: {} });\n\ntest('Throw error if \"config\" doesn`t exist', async (t) => {\n  await t.throwsAsync(loadChangelogConfig({ config: \"unknown-config\" }, { cwd }), { code: \"MODULE_NOT_FOUND\" });\n});\n\ntest('Throw error if \"preset\" doesn`t exist', async (t) => {\n  await t.throwsAsync(loadChangelogConfig({ preset: \"unknown-preset\" }, { cwd }), { code: \"MODULE_NOT_FOUND\" });\n});\n\ntest.serial(\"Load preset and config correctly when importFrom.silent fails\", async (t) => {\n  sinon.stub(importFrom, \"silent\").returns(undefined);\n\n  await loadPreset(t, \"angular\");\n  await loadConfig(t, \"angular\");\n\n  sinon.restore();\n});\n"
  },
  {
    "path": "wrappers/conventional-changelog-writer.js",
    "content": "import { writeChangelogStream as writer } from 'conventional-changelog-writer';\n\nexport default writer;\n"
  }
]