conventional-changelog-preset-loader
Advanced tools
Comparing version 3.0.0 to 4.0.0
151
index.js
'use strict' | ||
const nodePath = require('path') | ||
const path = require('path') | ||
module.exports = presetLoader(require) | ||
module.exports.presetLoader = presetLoader | ||
module.exports.loadPreset = createPresetLoader((preset) => import(preset)) | ||
module.exports.createPresetLoader = createPresetLoader | ||
function presetLoader (requireMethod) { | ||
return path => { | ||
let name = '' | ||
let scope = '' | ||
let absolutePath = '' | ||
/** | ||
* @typedef {((moduleName: string) => any) | ((moduleName: string) => Promise<any>)} ModuleLoader | ||
*/ | ||
if (typeof path === 'string') { | ||
name = path.toLowerCase() | ||
if (nodePath.isAbsolute(path)) { | ||
absolutePath = path | ||
} | ||
} else if (typeof path === 'object' && path.name) { | ||
// Rather than a string preset name, options.preset can be an object | ||
// with a "name" key indicating the preset to load; additinoal key/value | ||
// pairs are assumed to be configuration for the preset. See the documentation | ||
// for a given preset for configuration available. | ||
name = path.name.toLowerCase() | ||
if (nodePath.isAbsolute(path.name)) { | ||
absolutePath = path.name | ||
} | ||
} else { | ||
throw Error('preset must be string or object with key name') | ||
/** | ||
* @typedef {{ name: string }} PresetParams | ||
*/ | ||
/** | ||
* Trying to add 'conventional-changelog-' prefix to preset name if it is a shorthand. | ||
* @param {string} preset - Absolute path, package name or shorthand preset name. | ||
* @returns Variants of preset names. | ||
*/ | ||
function resolvePresetNameVariants (preset) { | ||
if (path.isAbsolute(preset)) { | ||
return [preset] | ||
} | ||
let scope = '' | ||
let name = preset.toLocaleLowerCase() | ||
if (preset[0] === '@') { | ||
const parts = preset.split('/') | ||
scope = parts.shift() + '/' | ||
if (scope === '@conventional-changelog/') { | ||
return [preset] | ||
} | ||
if (!absolutePath) { | ||
if (name[0] === '@') { | ||
const parts = name.split('/') | ||
scope = parts.shift() + '/' | ||
name = parts.join('/') | ||
} | ||
name = parts.join('/') | ||
} | ||
if (!name.startsWith('conventional-changelog-')) { | ||
name = `conventional-changelog-${name}` | ||
if (!name.startsWith('conventional-changelog-')) { | ||
name = `conventional-changelog-${name}` | ||
} | ||
const altPreset = `${scope}${name}` | ||
if (altPreset !== preset) { | ||
return [altPreset, preset] | ||
} | ||
return [preset] | ||
} | ||
/** | ||
* Loads module with fallbacks. | ||
* @param {ModuleLoader} moduleLoader - Function that loads module. | ||
* @param {string[]} variants - Variants of module name to try. | ||
* @returns {Promise<any>} Loaded module. | ||
*/ | ||
async function loadWithFallbacks (moduleLoader, variants) { | ||
let error = null | ||
for (const variant of variants) { | ||
try { | ||
return await moduleLoader(variant) | ||
} catch (err) { | ||
if (!error) { | ||
error = err | ||
} | ||
} | ||
} | ||
throw error | ||
} | ||
/** | ||
* Gets default export from CommonJS or ES module. | ||
* @param {object} module | ||
* @returns {object} | ||
*/ | ||
function getModuleDefaultExport (module) { | ||
if ((module.__esModule || Object.getPrototypeOf(module) === null) && module.default) { | ||
return module.default | ||
} | ||
return module | ||
} | ||
/** | ||
* Creates preset loader. | ||
* @param {ModuleLoader} moduleLoader - Function that loads module. | ||
* @returns {(presetOrParams: string | PresetParams) => Promise<any>} Function that loads preset. | ||
*/ | ||
function createPresetLoader (moduleLoader) { | ||
return async function loadPreset (presetOrParams) { | ||
let preset = '' | ||
let params = null | ||
if (typeof presetOrParams === 'string') { | ||
preset = presetOrParams | ||
} else | ||
if (typeof presetOrParams === 'object' && typeof presetOrParams.name === 'string') { | ||
preset = presetOrParams.name | ||
params = presetOrParams | ||
} else { | ||
throw Error('Preset must be string or object with property `name`') | ||
} | ||
const presetNameVariants = resolvePresetNameVariants(preset) | ||
let createPreset = null | ||
try { | ||
const config = requireMethod(absolutePath || `${scope}${name}`) | ||
// rather than returning a promise, presets can return a builder function | ||
// which accepts a config object (allowing for customization) and returns | ||
// a promise. | ||
if (config && !config.then && typeof path === 'object') { | ||
return config(path) | ||
} else { | ||
// require returned a promise that resolves to a config object. | ||
return config | ||
} | ||
} catch (_) { | ||
throw Error('does not exist') | ||
createPreset = getModuleDefaultExport(await loadWithFallbacks(moduleLoader, presetNameVariants)) | ||
} catch (err) { | ||
throw Error(`Unable to load the "${preset}" preset. Please make sure it's installed.`, { cause: err }) | ||
} | ||
return params | ||
? await createPreset(params) | ||
: await createPreset() | ||
} | ||
} |
{ | ||
"name": "conventional-changelog-preset-loader", | ||
"version": "3.0.0", | ||
"version": "4.0.0", | ||
"description": "Configuration preset loader for `conventional-changelog`.", | ||
@@ -16,3 +16,3 @@ "repository": { | ||
"engines": { | ||
"node": ">=14" | ||
"node": ">=16" | ||
}, | ||
@@ -27,9 +27,5 @@ "files": [ | ||
"devDependencies": { | ||
"conventional-changelog-angular": "^6.0.0", | ||
"conventional-changelog-conventionalcommits": "^6.0.0", | ||
"sinon": "^12.0.1" | ||
}, | ||
"scripts": { | ||
"test-windows": "mocha --timeout 30000" | ||
"conventional-changelog-angular": "^7.0.0", | ||
"conventional-changelog-conventionalcommits": "^7.0.0" | ||
} | ||
} |
103
README.md
@@ -1,41 +0,98 @@ | ||
# [![NPM version][npm-image]][npm-url] [![Build Status: Linux][travis-image]][travis-url] [![Build Status: Windows][appveyor-image]][appveyor-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage Status][coverage-image]][coverage-url] | ||
# conventional-changelog-preset-loader | ||
> Configuration preset loader for `conventional-changelog`. | ||
[![NPM version][npm]][npm-url] | ||
[![Node version][node]][node-url] | ||
[![Dependencies status][deps]][deps-url] | ||
[![Build status][build]][build-url] | ||
[![Coverage status][coverage]][coverage-url] | ||
[npm]: https://img.shields.io/npm/v/conventional-changelog-preset-loader.svg | ||
[npm-url]: https://npmjs.com/package/conventional-changelog-preset-loader | ||
[node]: https://img.shields.io/node/v/conventional-changelog-preset-loader.svg | ||
[node-url]: https://nodejs.org | ||
[deps]: https://img.shields.io/librariesio/release/npm/conventional-changelog-preset-loader | ||
[deps-url]: https://libraries.io/npm/conventional-changelog-preset-loader/tree | ||
[build]: https://img.shields.io/github/actions/workflow/status/conventional-changelog/conventional-changelog/ci.yaml?branch=master | ||
[build-url]: https://github.com/conventional-changelog/conventional-changelog/actions | ||
[coverage]: https://coveralls.io/repos/github/conventional-changelog/conventional-changelog/badge.svg?branch=master | ||
[coverage-url]: https://coveralls.io/github/conventional-changelog/conventional-changelog?branch=master | ||
Configuration preset loader for `conventional-changelog`. | ||
## Usage | ||
```sh | ||
$ npm install --save conventional-changelog-preset-loader | ||
Install: | ||
```bash | ||
# yarn | ||
yarn add -D conventional-changelog-preset-loader | ||
# pnpm | ||
pnpm add -D conventional-changelog-preset-loader | ||
# npm | ||
npm i -D conventional-changelog-preset-loader | ||
``` | ||
Import `loadPreset` function from the package and use it to load the preset: | ||
```js | ||
var conventionalChangelogPresetLoader = require('conventional-changelog-preset-loader'); | ||
const { loadPreset } = require('conventional-changelog-preset-loader') | ||
configuration = conventionalChangelogPresetLoader(`angular`); | ||
loadPreset('angular').then((config) => { | ||
// do something with config object | ||
}) | ||
``` | ||
By default it uses `import` to load preset. If you want to use `require` instead, you can create own loader with `createPresetLoader` function: | ||
The string that is passed to the preset loader is manipulated by prepending `conventional-changelog` to the name. | ||
```js | ||
const { createPresetLoader } = require('conventional-changelog-preset-loader') | ||
const loadPreset = createPresetLoader(require) | ||
``` | ||
## Preset package resolution | ||
Firstly, loader will try prepend `conventional-changelog` to the preset name and load it. | ||
For example: | ||
* `angular` => `conventional-changelog-angular` | ||
* `angular/preset/path` => `conventional-changelog-angular/preset/path` | ||
* `@scope/angular` => `@scope/conventional-changelog-angular` | ||
* `@scope/angular/preset/path` => `@scope/conventional-changelog-angular/preset/path` | ||
- `angular` => `conventional-changelog-angular` | ||
- `angular/preset/path` => `conventional-changelog-angular/preset/path` | ||
- `@scope/angular` => `@scope/conventional-changelog-angular` | ||
- `@scope/angular/preset/path` => `@scope/conventional-changelog-angular/preset/path` | ||
Will return whatever is exported by the preset package. That may be a configuration object, a function, or a promise. | ||
If it fails, it will try to load preset using name as is. | ||
## Preset exports | ||
Preset package should have default export which is a async (returns `Promise`) or sync function that accepts optional `options` object and returns the config object: | ||
```js | ||
export default function createPreset(options) { | ||
return { | ||
// config | ||
} | ||
} | ||
``` | ||
## Preset options | ||
To pass options to the preset, `loadPreset` function accepts object with `name` property as first argument: | ||
```js | ||
const { loadPreset } = require('conventional-changelog-preset-loader') | ||
loadPreset({ | ||
name: 'angular', | ||
...presetOptions | ||
}).then((config) => { | ||
// do something with config object | ||
}) | ||
``` | ||
## License | ||
MIT © [Steve Mao](https://github.com/stevemao) | ||
[npm-image]: https://badge.fury.io/js/conventional-changelog-preset-loader.svg | ||
[npm-url]: https://npmjs.org/package/conventional-changelog-preset-loader | ||
[travis-image]: https://travis-ci.org/conventional-changelog/conventional-changelog-preset-loader.svg?branch=master | ||
[travis-url]: https://travis-ci.org/conventional-changelog/conventional-changelog-preset-loader | ||
[appveyor-image]: https://ci.appveyor.com/api/projects/status/baoumm34w8c5o0hv/branch/master?svg=true | ||
[appveyor-url]: https://ci.appveyor.com/project/stevemao/conventional-changelog-preset-loader/branch/master | ||
[daviddm-image]: https://david-dm.org/conventional-changelog/conventional-changelog-preset-loader.svg?theme=shields.io | ||
[daviddm-url]: https://david-dm.org/conventional-changelog/conventional-changelog-preset-loader | ||
[coverage-image]: https://coveralls.io/repos/github/conventional-changelog/conventional-changelog/badge.svg?branch=master | ||
[coverage-url]: https://coveralls.io/github/conventional-changelog/conventional-changelog?branch=master |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
7981
2
98
99
0