vfile-sort
Advanced tools
Comparing version 3.0.1 to 4.0.0
@@ -1,1 +0,1 @@ | ||
export {sort} from './lib/index.js' | ||
export {compareFile, compareMessage} from './lib/index.js' |
@@ -1,1 +0,1 @@ | ||
export {sort} from './lib/index.js' | ||
export {compareFile, compareMessage} from './lib/index.js' |
/** | ||
* Sort messages in the given vfile. | ||
* @typedef {import('vfile').VFile} VFile | ||
* @typedef {import('vfile-message').VFileMessage} VFileMessage | ||
*/ | ||
/** | ||
* @template Thing | ||
* @template Kind | ||
* @typedef {{[Key in keyof Thing]: NonNullable<Thing[Key]> extends Kind ? Key : never}[keyof Thing]} KeysOfType | ||
* Complex type that finds the keys of fields whose values are of a certain | ||
* type `Kind` (such as `string`) in `Thing` (probably an object). | ||
*/ | ||
/** | ||
* Compare files. | ||
* | ||
* @template {VFile} File | ||
* File type. | ||
* @param {File} file | ||
* File to sort. | ||
* @returns {File} | ||
* Sorted file. | ||
* @since | ||
* 4.0.0 | ||
* @param {VFile} a | ||
* File. | ||
* @param {VFile} b | ||
* Other file. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
export function sort<File extends import('vfile').VFile>(file: File): File | ||
export function compareFile(a: VFile, b: VFile): number | ||
/** | ||
* Compare messages. | ||
* | ||
* ###### Algorithm | ||
* | ||
* It first sorts by line/column: earlier messages come first. | ||
* When two messages occurr at the same place, sorts fatal error before | ||
* warnings, before info messages. | ||
* Finally, it sorts using `localeCompare` on `source`, `ruleId`, or finally | ||
* `reason`. | ||
* | ||
* @since | ||
* 4.0.0 | ||
* @param {VFileMessage} a | ||
* Message. | ||
* @param {VFileMessage} b | ||
* Other message. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
export function compareMessage(a: VFileMessage, b: VFileMessage): number | ||
export type VFile = import('vfile').VFile | ||
export type VFileMessage = import('vfile-message').VFileMessage | ||
/** | ||
* Complex type that finds the keys of fields whose values are of a certain | ||
* type `Kind` (such as `string`) in `Thing` (probably an object). | ||
*/ | ||
export type KeysOfType<Thing, Kind> = { | ||
[Key in keyof Thing]: NonNullable<Thing[Key]> extends Kind ? Key : never | ||
}[keyof Thing] |
124
lib/index.js
@@ -6,40 +6,54 @@ /** | ||
/** @type {Record<string, number>} */ | ||
const severities = {true: 2, false: 1, null: 0, undefined: 0} | ||
/** | ||
* @template Thing | ||
* @template Kind | ||
* @typedef {{[Key in keyof Thing]: NonNullable<Thing[Key]> extends Kind ? Key : never}[keyof Thing]} KeysOfType | ||
* Complex type that finds the keys of fields whose values are of a certain | ||
* type `Kind` (such as `string`) in `Thing` (probably an object). | ||
*/ | ||
/** | ||
* Sort messages in the given vfile. | ||
* Compare files. | ||
* | ||
* @template {VFile} File | ||
* File type. | ||
* @param {File} file | ||
* File to sort. | ||
* @returns {File} | ||
* Sorted file. | ||
* @since | ||
* 4.0.0 | ||
* @param {VFile} a | ||
* File. | ||
* @param {VFile} b | ||
* Other file. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
// To do: next major: don’t return `file`. | ||
export function sort(file) { | ||
file.messages.sort(comparator) | ||
return file | ||
export function compareFile(a, b) { | ||
return compareString(a, b, 'path') | ||
} | ||
/** | ||
* Compare a message. | ||
* Compare messages. | ||
* | ||
* ###### Algorithm | ||
* | ||
* It first sorts by line/column: earlier messages come first. | ||
* When two messages occurr at the same place, sorts fatal error before | ||
* warnings, before info messages. | ||
* Finally, it sorts using `localeCompare` on `source`, `ruleId`, or finally | ||
* `reason`. | ||
* | ||
* @since | ||
* 4.0.0 | ||
* @param {VFileMessage} a | ||
* Left message. | ||
* Message. | ||
* @param {VFileMessage} b | ||
* Right message. | ||
* Other message. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
function comparator(a, b) { | ||
export function compareMessage(a, b) { | ||
return ( | ||
check(a, b, 'line') || | ||
check(a, b, 'column') || | ||
severities[String(b.fatal)] - severities[String(a.fatal)] || | ||
compare(a, b, 'source') || | ||
compare(a, b, 'ruleId') || | ||
compare(a, b, 'reason') || | ||
0 | ||
compareNumber(a, b, 'line') || | ||
compareNumber(a, b, 'column') || | ||
compareBoolean(a, b, 'fatal') || | ||
compareString(a, b, 'source') || | ||
compareString(a, b, 'ruleId') || | ||
compareString(a, b, 'reason') | ||
) | ||
@@ -49,14 +63,34 @@ } | ||
/** | ||
* Compare a boolean field. | ||
* | ||
* @template {object} Thing | ||
* Thing type. | ||
* @param {Thing} a | ||
* Left thing. | ||
* @param {Thing} b | ||
* Right thing. | ||
* @param {KeysOfType<Thing, boolean>} field | ||
* Key of boolean field. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
function compareBoolean(a, b, field) { | ||
return scoreNullableBoolean(a[field]) - scoreNullableBoolean(b[field]) | ||
} | ||
/** | ||
* Compare a numeric field. | ||
* | ||
* @param {VFileMessage} a | ||
* Left message. | ||
* @param {VFileMessage} b | ||
* Right message. | ||
* @param {'column' | 'line'} field | ||
* Numeric field. | ||
* @template {object} Thing | ||
* Thing type. | ||
* @param {Thing} a | ||
* Left thing. | ||
* @param {Thing} b | ||
* Right thing. | ||
* @param {KeysOfType<Thing, number>} field | ||
* Key of number field. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
function check(a, b, field) { | ||
function compareNumber(a, b, field) { | ||
return (a[field] || 0) - (b[field] || 0) | ||
@@ -66,13 +100,25 @@ } | ||
/** | ||
* @param {VFileMessage} a | ||
* Left message. | ||
* @param {VFileMessage} b | ||
* Right message. | ||
* @param {'reason' | 'ruleId' | 'source'} field | ||
* String field. | ||
* @template {object} Thing | ||
* Thing type. | ||
* @param {Thing} a | ||
* Left thing. | ||
* @param {Thing} b | ||
* Right thing. | ||
* @param {KeysOfType<Thing, string>} field | ||
* Key of string field. | ||
* @returns {number} | ||
* Order. | ||
*/ | ||
function compare(a, b, field) { | ||
return String(a[field] || '').localeCompare(b[field] || '') | ||
function compareString(a, b, field) { | ||
return String(a[field] || '').localeCompare(String(b[field] || '')) | ||
} | ||
/** | ||
* @param {boolean | null | undefined} value | ||
* Value | ||
* @returns {number} | ||
* Score. | ||
*/ | ||
function scoreNullableBoolean(value) { | ||
return value ? 0 : value === false ? 1 : 2 | ||
} |
{ | ||
"name": "vfile-sort", | ||
"version": "3.0.1", | ||
"version": "4.0.0", | ||
"description": "vfile utility to sort messages by line/column", | ||
@@ -29,4 +29,3 @@ "license": "MIT", | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"exports": "./index.js", | ||
"files": [ | ||
@@ -38,7 +37,7 @@ "lib/", | ||
"dependencies": { | ||
"vfile": "^5.0.0", | ||
"vfile-message": "^3.0.0" | ||
"vfile": "^6.0.0", | ||
"vfile-message": "^4.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.0.0", | ||
"@types/node": "^20.0.0", | ||
"c8": "^7.0.0", | ||
@@ -49,4 +48,4 @@ "prettier": "^2.0.0", | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"xo": "^0.53.0" | ||
"typescript": "^5.0.0", | ||
"xo": "^0.54.0" | ||
}, | ||
@@ -58,19 +57,16 @@ "scripts": { | ||
"test-api": "node --conditions development test.js", | ||
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", | ||
"test-coverage": "c8 --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
"prettier": { | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": true, | ||
"bracketSpacing": false, | ||
"semi": false, | ||
"trailingComma": "none" | ||
"singleQuote": true, | ||
"tabWidth": 2, | ||
"trailingComma": "none", | ||
"useTabs": false | ||
}, | ||
"xo": { | ||
"prettier": true | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-wooorm" | ||
"remark-preset-wooorm" | ||
] | ||
@@ -81,4 +77,8 @@ }, | ||
"detail": true, | ||
"ignoreCatch": true, | ||
"strict": true | ||
}, | ||
"xo": { | ||
"prettier": true | ||
} | ||
} |
100
readme.md
@@ -11,3 +11,3 @@ # vfile-sort | ||
[`vfile`][vfile] utility to sort messages. | ||
[`vfile`][vfile] utility to sort files or messages. | ||
@@ -21,3 +21,4 @@ ## Contents | ||
* [API](#api) | ||
* [`sort(file)`](#sortfile) | ||
* [`compareFile(a, b)`](#comparefilea-b) | ||
* [`compareMessage(a, b)`](#comparemessagea-b) | ||
* [Types](#types) | ||
@@ -30,8 +31,3 @@ * [Compatibility](#compatibility) | ||
This is a small package to sort the list of messages. | ||
It first sorts by line/column: earlier messages come first. | ||
When two messages occurr at the same place, sorts fatal error before warnings, | ||
before info messages. | ||
Finally, it sorts using `localeCompare` on `source`, `ruleId`, or finally | ||
`reason`. | ||
This package exposes comparators for vfile files and messages. | ||
@@ -46,3 +42,3 @@ ## When should I use this? | ||
This package is [ESM only][esm]. | ||
In Node.js (version 14.14+ and 16.0+), install with [npm][]: | ||
In Node.js (version 16+), install with [npm][]: | ||
@@ -56,3 +52,3 @@ ```sh | ||
```js | ||
import {sort} from 'https://esm.sh/vfile-sort@3' | ||
import {sort} from 'https://esm.sh/vfile-sort@4' | ||
``` | ||
@@ -64,3 +60,3 @@ | ||
<script type="module"> | ||
import {sort} from 'https://esm.sh/vfile-sort@3?bundle' | ||
import {sort} from 'https://esm.sh/vfile-sort@4?bundle' | ||
</script> | ||
@@ -73,13 +69,22 @@ ``` | ||
import {VFile} from 'vfile' | ||
import {sort} from 'vfile-sort' | ||
import {VFileMessage} from 'vfile-message' | ||
import {compareFile, compareMessage} from 'vfile-sort' | ||
const file = VFile() | ||
console.log( | ||
[ | ||
new VFileMessage('Error!', {place: {line: 3, column: 1}}), | ||
new VFileMessage('Another!', {place: {line: 2, column: 2}}) | ||
] | ||
.toSorted(compareMessage) | ||
.map(String) | ||
) //=> ['2:2: Another!', '3:1: Error!'] | ||
file.message('Error!', {line: 3, column: 1}) | ||
file.message('Another!', {line: 2, column: 2}) | ||
sort(file) | ||
console.log(file.messages.map(d => String(d))) | ||
// => ['2:2: Another!', '3:1: Error!'] | ||
console.log( | ||
[ | ||
new VFile(new URL(import.meta.url)), | ||
new VFile(new URL('.', import.meta.url)) | ||
] | ||
.toSorted(compareFile) | ||
.map((d) => d.path) | ||
) //=> ['/Users/tilde/Projects/oss/vfile-sort/', '/Users/tilde/Projects/oss/vfile-sort/example.js'] | ||
``` | ||
@@ -89,18 +94,44 @@ | ||
This package exports the identifier [`sort`][api-sort]. | ||
This package exports the identifiers [`compareFile`][api-compare-file] and | ||
[`compareMessage`][api-compare-message]. | ||
There is no default export. | ||
### `sort(file)` | ||
### `compareFile(a, b)` | ||
Sort messages in the given [vfile][]. | ||
Compare files (since: `4.0.0`). | ||
###### Parameters | ||
* `file` ([`VFile`][vfile]) | ||
— file to sort | ||
* `a` ([`VFile`][vfile]) | ||
— file | ||
* `b` ([`VFile`][vfile]) | ||
— other file | ||
###### Returns | ||
Sorted file ([`VFile`][vfile]). | ||
Order (`number`). | ||
### `compareMessage(a, b)` | ||
Compare messages (since: `4.0.0`). | ||
###### Algorithm | ||
It first sorts by line/column: earlier messages come first. | ||
When two messages occurr at the same place, sorts fatal error before | ||
warnings, before info messages. | ||
Finally, it sorts using `localeCompare` on `source`, `ruleId`, or finally | ||
`reason`. | ||
###### Parameters | ||
* `a` ([`VFile`][vfile]) | ||
— message | ||
* `b` ([`VFile`][vfile]) | ||
— other message | ||
###### Returns | ||
Order (`number`). | ||
## Types | ||
@@ -113,7 +144,10 @@ | ||
Projects maintained by the unified collective are compatible with all maintained | ||
Projects maintained by the unified collective are compatible with maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 14.14+ and 16.0+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
When we cut a new major release, we drop support for unmaintained versions of | ||
Node. | ||
This means we try to keep the current release line, `vfile-sort@^4`, | ||
compatible with Node.js 16. | ||
## Contribute | ||
@@ -147,5 +181,5 @@ | ||
[size-badge]: https://img.shields.io/bundlephobia/minzip/vfile-sort.svg | ||
[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=vfile-sort | ||
[size]: https://bundlephobia.com/result?p=vfile-sort | ||
[size]: https://bundlejs.com/?q=vfile-sort | ||
@@ -184,2 +218,4 @@ [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg | ||
[api-sort]: #sortfile | ||
[api-compare-file]: #comparefilea-b | ||
[api-compare-message]: #comparemessagea-b |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
12281
170
211
1
+ Added@types/unist@3.0.2(transitive)
+ Addedunist-util-stringify-position@4.0.0(transitive)
+ Addedvfile@6.0.1(transitive)
+ Addedvfile-message@4.0.2(transitive)
- Removed@types/unist@2.0.10(transitive)
- Removedis-buffer@2.0.5(transitive)
- Removedunist-util-stringify-position@3.0.3(transitive)
- Removedvfile@5.3.7(transitive)
- Removedvfile-message@3.1.4(transitive)
Updatedvfile@^6.0.0
Updatedvfile-message@^4.0.0