vfile-message
Advanced tools
Comparing version 3.1.4 to 4.0.0
@@ -0,1 +1,5 @@ | ||
/** | ||
* @typedef {import('./lib/index.js').Options} Options | ||
*/ | ||
export {VFileMessage} from './lib/index.js' |
305
lib/index.js
/** | ||
* @typedef {import('unist').Node} Node | ||
* @typedef {import('unist').Point} Point | ||
* @typedef {import('unist').Position} Position | ||
* @typedef {import('unist').Point} Point | ||
*/ | ||
/** | ||
* @typedef {object & {type: string, position?: Position | undefined}} NodeLike | ||
* | ||
* @typedef Options | ||
* Configuration. | ||
* @property {Array<Node> | null | undefined} [ancestors] | ||
* Stack of (inclusive) ancestor nodes surrounding the message (optional). | ||
* @property {Error | null | undefined} [cause] | ||
* Original error cause of the message (optional). | ||
* @property {Point | Position | null | undefined} [place] | ||
* Place of message (optional). | ||
* @property {string | null | undefined} [ruleId] | ||
* Category of message (optional, example: `'my-rule'`). | ||
* @property {string | null | undefined} [source] | ||
* Namespace of who sent the message (optional, example: `'my-package'`). | ||
*/ | ||
@@ -15,13 +31,50 @@ | ||
/** | ||
* Create a message for `reason` at `place` from `origin`. | ||
* Create a message for `reason`. | ||
* | ||
* When an error is passed in as `reason`, the `stack` is copied. | ||
* > πͺ¦ **Note**: also has obsolete signatures. | ||
* | ||
* @param {string | Error | VFileMessage} reason | ||
* Reason for message, uses the stack and message of the error if given. | ||
* @overload | ||
* @param {string} reason | ||
* @param {Options | null | undefined} [options] | ||
* @returns | ||
* | ||
* > π **Note**: you should use markdown. | ||
* @param {Node | NodeLike | Position | Point | null | undefined} [place] | ||
* Place in file where the message occurred. | ||
* @overload | ||
* @param {string} reason | ||
* @param {Node | NodeLike | null | undefined} parent | ||
* @param {string | null | undefined} [origin] | ||
* @returns | ||
* | ||
* @overload | ||
* @param {string} reason | ||
* @param {Point | Position | null | undefined} place | ||
* @param {string | null | undefined} [origin] | ||
* @returns | ||
* | ||
* @overload | ||
* @param {string} reason | ||
* @param {string | null | undefined} [origin] | ||
* @returns | ||
* | ||
* @overload | ||
* @param {Error | VFileMessage} cause | ||
* @param {Node | NodeLike | null | undefined} parent | ||
* @param {string | null | undefined} [origin] | ||
* @returns | ||
* | ||
* @overload | ||
* @param {Error | VFileMessage} cause | ||
* @param {Point | Position | null | undefined} place | ||
* @param {string | null | undefined} [origin] | ||
* @returns | ||
* | ||
* @overload | ||
* @param {Error | VFileMessage} cause | ||
* @param {string | null | undefined} [origin] | ||
* @returns | ||
* | ||
* @param {Error | VFileMessage | string} causeOrReason | ||
* Reason for message, should use markdown. | ||
* @param {Node | NodeLike | Options | Point | Position | string | null | undefined} [optionsOrParentOrPlace] | ||
* Configuration (optional). | ||
* @param {string | null | undefined} [origin] | ||
* Place in code where the message originates (example: | ||
@@ -32,104 +85,126 @@ * `'my-package:my-rule'` or `'my-rule'`). | ||
*/ | ||
// To do: next major: expose `undefined` everywhere instead of `null`. | ||
constructor(reason, place, origin) { | ||
/** @type {[string | null, string | null]} */ | ||
const parts = [null, null] | ||
/** @type {Position} */ | ||
let position = { | ||
// @ts-expect-error: we always follows the structure of `position`. | ||
start: {line: null, column: null}, | ||
// @ts-expect-error: " | ||
end: {line: null, column: null} | ||
// eslint-disable-next-line complexity | ||
constructor(causeOrReason, optionsOrParentOrPlace, origin) { | ||
super() | ||
if (typeof optionsOrParentOrPlace === 'string') { | ||
origin = optionsOrParentOrPlace | ||
optionsOrParentOrPlace = undefined | ||
} | ||
super() | ||
/** @type {string} */ | ||
let reason = '' | ||
/** @type {Options} */ | ||
let options = {} | ||
let legacyCause = false | ||
if (typeof place === 'string') { | ||
origin = place | ||
place = undefined | ||
if (optionsOrParentOrPlace) { | ||
// Point. | ||
if ( | ||
'line' in optionsOrParentOrPlace && | ||
'column' in optionsOrParentOrPlace | ||
) { | ||
options = {place: optionsOrParentOrPlace} | ||
} | ||
// Position. | ||
else if ( | ||
'start' in optionsOrParentOrPlace && | ||
'end' in optionsOrParentOrPlace | ||
) { | ||
options = {place: optionsOrParentOrPlace} | ||
} | ||
// Node. | ||
else if ('type' in optionsOrParentOrPlace) { | ||
options = { | ||
ancestors: [optionsOrParentOrPlace], | ||
place: optionsOrParentOrPlace.position | ||
} | ||
} | ||
// Options. | ||
else { | ||
options = {...optionsOrParentOrPlace} | ||
} | ||
} | ||
if (typeof origin === 'string') { | ||
if (typeof causeOrReason === 'string') { | ||
reason = causeOrReason | ||
} | ||
// Error. | ||
else if (!options.cause && causeOrReason) { | ||
legacyCause = true | ||
reason = causeOrReason.message | ||
options.cause = causeOrReason | ||
} | ||
if (!options.ruleId && !options.source && typeof origin === 'string') { | ||
const index = origin.indexOf(':') | ||
if (index === -1) { | ||
parts[1] = origin | ||
options.ruleId = origin | ||
} else { | ||
parts[0] = origin.slice(0, index) | ||
parts[1] = origin.slice(index + 1) | ||
options.source = origin.slice(0, index) | ||
options.ruleId = origin.slice(index + 1) | ||
} | ||
} | ||
if (place) { | ||
// Node. | ||
if ('type' in place || 'position' in place) { | ||
if (place.position) { | ||
// To do: next major: deep clone. | ||
// @ts-expect-error: looks like a position. | ||
position = place.position | ||
} | ||
if (!options.place && options.ancestors && options.ancestors) { | ||
const parent = options.ancestors[options.ancestors.length - 1] | ||
if (parent) { | ||
options.place = parent.position | ||
} | ||
// Position. | ||
else if ('start' in place || 'end' in place) { | ||
// @ts-expect-error: looks like a position. | ||
// To do: next major: deep clone. | ||
position = place | ||
} | ||
// Point. | ||
else if ('line' in place || 'column' in place) { | ||
// To do: next major: deep clone. | ||
position.start = place | ||
} | ||
} | ||
// Fields from `Error`. | ||
const start = | ||
options.place && 'start' in options.place | ||
? options.place.start | ||
: options.place | ||
/* eslint-disable no-unused-expressions */ | ||
/** | ||
* Serialized positional info of error. | ||
* Stack of ancestor nodes surrounding the message. | ||
* | ||
* On normal errors, this would be something like `ParseError`, buit in | ||
* `VFile` messages we use this space to show where an error happened. | ||
* @type {Array<Node> | undefined} | ||
*/ | ||
this.name = stringifyPosition(place) || '1:1' | ||
this.ancestors = options.ancestors || undefined | ||
/** | ||
* Reason for message. | ||
* Original error cause of the message. | ||
* | ||
* @type {string} | ||
* @type {Error | undefined} | ||
*/ | ||
this.message = typeof reason === 'object' ? reason.message : reason | ||
this.cause = options.cause || undefined | ||
/** | ||
* Stack of message. | ||
* Starting column of message. | ||
* | ||
* This is used by normal errors to show where something happened in | ||
* programming code, irrelevant for `VFile` messages, | ||
* | ||
* @type {string} | ||
* @type {number | undefined} | ||
*/ | ||
this.stack = '' | ||
this.column = start ? start.column : undefined | ||
if (typeof reason === 'object' && reason.stack) { | ||
this.stack = reason.stack | ||
} | ||
/** | ||
* Reason for message. | ||
* State of problem. | ||
* | ||
* > π **Note**: you should use markdown. | ||
* * `true` β error, file not usable | ||
* * `false` β warning, change may be needed | ||
* * `undefined` β change likely not needed | ||
* | ||
* @type {string} | ||
* @type {boolean | null | undefined} | ||
*/ | ||
this.reason = this.message | ||
this.fatal = undefined | ||
/* eslint-disable no-unused-expressions */ | ||
/** | ||
* State of problem. | ||
* Path of a file (used throughout the `VFile` ecosystem). | ||
* | ||
* * `true` β marks associated file as no longer processable (error) | ||
* * `false` β necessitates a (potential) change (warning) | ||
* * `null | undefined` β for things that might not need changing (info) | ||
* @type {string | undefined} | ||
*/ | ||
this.file | ||
// Field from `Error`. | ||
/** | ||
* Reason for message. | ||
* | ||
* @type {boolean | null | undefined} | ||
* @type {string} | ||
*/ | ||
this.fatal | ||
this.message = reason | ||
@@ -139,26 +214,28 @@ /** | ||
* | ||
* @type {number | null} | ||
* @type {number | undefined} | ||
*/ | ||
this.line = position.start.line | ||
this.line = start ? start.line : undefined | ||
// Field from `Error`. | ||
/** | ||
* Starting column of error. | ||
* Serialized positional info of message. | ||
* | ||
* @type {number | null} | ||
* On normal errors, this would be something like `ParseError`, buit in | ||
* `VFile` messages we use this space to show where an error happened. | ||
*/ | ||
this.column = position.start.column | ||
this.name = stringifyPosition(options.place) || '1:1' | ||
/** | ||
* Full unist position. | ||
* Place of message. | ||
* | ||
* @type {Position | null} | ||
* @type {Point | Position | undefined} | ||
*/ | ||
this.position = position | ||
this.place = options.place || undefined | ||
/** | ||
* Namespace of message (example: `'my-package'`). | ||
* Reason for message, should use markdown. | ||
* | ||
* @type {string | null} | ||
* @type {string} | ||
*/ | ||
this.source = parts[0] | ||
this.reason = this.message | ||
@@ -168,13 +245,27 @@ /** | ||
* | ||
* @type {string | null} | ||
* @type {string | undefined} | ||
*/ | ||
this.ruleId = parts[1] | ||
this.ruleId = options.ruleId || undefined | ||
/** | ||
* Path of a file (used throughout the `VFile` ecosystem). | ||
* Namespace of message (example: `'my-package'`). | ||
* | ||
* @type {string | null} | ||
* @type {string | undefined} | ||
*/ | ||
this.file | ||
this.source = options.source || undefined | ||
// Field from `Error`. | ||
/** | ||
* Stack of message. | ||
* | ||
* This is used by normal errors to show where something happened in | ||
* programming code, irrelevant for `VFile` messages, | ||
* | ||
* @type {string} | ||
*/ | ||
this.stack = | ||
legacyCause && options.cause && typeof options.cause.stack === 'string' | ||
? options.cause.stack | ||
: '' | ||
// The following fields are βwell knownβ. | ||
@@ -188,3 +279,3 @@ // Not standard. | ||
* | ||
* @type {string | null} | ||
* @type {string | undefined} | ||
*/ | ||
@@ -196,3 +287,3 @@ this.actual | ||
* | ||
* @type {Array<string> | null} | ||
* @type {Array<string> | undefined} | ||
*/ | ||
@@ -202,2 +293,9 @@ this.expected | ||
/** | ||
* Long form description of the message (you should use markdown). | ||
* | ||
* @type {string | undefined} | ||
*/ | ||
this.note | ||
/** | ||
* Link to docs for the message. | ||
@@ -208,12 +306,5 @@ * | ||
* | ||
* @type {string | null} | ||
* @type {string | undefined} | ||
*/ | ||
this.url | ||
/** | ||
* Long form description of the message (you should use markdown). | ||
* | ||
* @type {string | null} | ||
*/ | ||
this.note | ||
/* eslint-enable no-unused-expressions */ | ||
@@ -228,7 +319,9 @@ } | ||
VFileMessage.prototype.stack = '' | ||
VFileMessage.prototype.fatal = null | ||
VFileMessage.prototype.column = null | ||
VFileMessage.prototype.line = null | ||
VFileMessage.prototype.source = null | ||
VFileMessage.prototype.ruleId = null | ||
VFileMessage.prototype.position = null | ||
VFileMessage.prototype.column = undefined | ||
VFileMessage.prototype.line = undefined | ||
VFileMessage.prototype.ancestors = undefined | ||
VFileMessage.prototype.cause = undefined | ||
VFileMessage.prototype.fatal = undefined | ||
VFileMessage.prototype.place = undefined | ||
VFileMessage.prototype.ruleId = undefined | ||
VFileMessage.prototype.source = undefined |
{ | ||
"name": "vfile-message", | ||
"version": "3.1.4", | ||
"version": "4.0.0", | ||
"description": "vfile utility to create a virtual message", | ||
@@ -27,9 +27,3 @@ "license": "MIT", | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"files": [ | ||
"lib/", | ||
"index.d.ts", | ||
"index.js" | ||
], | ||
"exports": "./index.js", | ||
"dependencies": { | ||
@@ -40,3 +34,3 @@ "@types/unist": "^2.0.0", | ||
"devDependencies": { | ||
"@types/node": "^18.0.0", | ||
"@types/node": "^20.0.0", | ||
"c8": "^7.0.0", | ||
@@ -47,4 +41,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" | ||
}, | ||
@@ -56,3 +50,3 @@ "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" | ||
@@ -68,8 +62,5 @@ }, | ||
}, | ||
"xo": { | ||
"prettier": true | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-wooorm" | ||
"remark-preset-wooorm" | ||
] | ||
@@ -82,3 +73,6 @@ }, | ||
"ignoreCatch": true | ||
}, | ||
"xo": { | ||
"prettier": true | ||
} | ||
} |
124
readme.md
@@ -20,3 +20,4 @@ # vfile-message | ||
* [API](#api) | ||
* [`VFileMessage(reason[, place][, origin])`](#vfilemessagereason-place-origin) | ||
* [`VFileMessage(reason[, options])`](#vfilemessagereason-options) | ||
* [`Options`](#options) | ||
* [Well-known](#well-known) | ||
@@ -41,3 +42,3 @@ * [Types](#types) | ||
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][]: | ||
@@ -51,3 +52,3 @@ ```sh | ||
```js | ||
import {VFileMessage} from 'https://esm.sh/vfile-message@3' | ||
import {VFileMessage} from 'https://esm.sh/vfile-message@4' | ||
``` | ||
@@ -59,3 +60,3 @@ | ||
<script type="module"> | ||
import {VFileMessage} from 'https://esm.sh/vfile-message@3?bundle' | ||
import {VFileMessage} from 'https://esm.sh/vfile-message@4?bundle' | ||
</script> | ||
@@ -71,4 +72,3 @@ ``` | ||
'Unexpected unknown word `braavo`, did you mean `bravo`?', | ||
{line: 1, column: 8}, | ||
'spell:typo' | ||
{source: 'spell', ruleId: 'typo', place: {line: 1, column: 8}} | ||
) | ||
@@ -86,5 +86,8 @@ | ||
column: 8, | ||
source: 'spell', | ||
ancestors: undefined, | ||
cause: undefined, | ||
fatal: undefined, | ||
place: {line: 1, column: 8}, | ||
ruleId: 'typo', | ||
position: {start: {line: 1, column: 8}, end: {line: null, column: null}} | ||
source: 'spell' | ||
} | ||
@@ -98,22 +101,18 @@ ``` | ||
### `VFileMessage(reason[, place][, origin])` | ||
### `VFileMessage(reason[, options])` | ||
Create a message for `reason` at `place` from `origin`. | ||
Create a message for `reason`. | ||
When an error is passed in as `reason`, the `stack` is copied. | ||
> πͺ¦ **Note**: also has obsolete signatures. | ||
###### Parameters | ||
* `reason` (`string` or `Error`) | ||
β reason for message, uses the stack and message of the error if given | ||
* `place` ([`Node`][node], [`Position`][position], or [`Point`][point], | ||
optional) | ||
β place in file where the message occurred | ||
* `origin` (`string`, optional) | ||
β place in code where the message originates (example: | ||
`'my-package:my-rule'` or `'my-rule'`) | ||
* `reason` (`string`) | ||
β reason for message (should use markdown) | ||
* `options` ([`Options`][api-options], optional) | ||
β configuration. | ||
###### Extends | ||
[`Error`][error]. | ||
[`Error`][mdn-error]. | ||
@@ -126,22 +125,38 @@ ###### Returns | ||
* `ancestors` ([`Array<Node>`][unist-node] or `undefined`) | ||
β stack of (inclusive) ancestor nodes surrounding the message | ||
* `cause` ([`Error`][mdn-error] or `undefined`) | ||
β original error cause of the message | ||
* `column` (`number` or `undefined`) | ||
β starting column of message | ||
* `fatal` (`boolean` or `undefined`) | ||
β state of problem; `true`: error, file not usable; `false`: warning, | ||
change may be needed; `undefined`: info, change likely not needed | ||
* `line` (`number` or `undefined`) | ||
β starting line of message | ||
* `place` ([`Point`][unist-point], [`Position`][unist-position] or `undefined`) | ||
β place of message | ||
* `reason` (`string`) | ||
β reason for message (you should use markdown) | ||
* `fatal` (`boolean | null | undefined`) | ||
β state of problem; `true` marks associated file as no longer processable | ||
(error); `false` necessitates a (potential) change (warning); | ||
`null | undefined` for things that might not need changing (info) | ||
* `line` (`number | null`) | ||
β starting line of error | ||
* `column` (`number | null`) | ||
β starting column of error | ||
* `position` ([`Position | null`][position]) | ||
β full unist position | ||
* `source` (`string | null`, example: `'my-package'`) | ||
β reason for message (should use markdown) | ||
* `ruleId` (`string` or `undefined`, example: `'my-rule'`) | ||
β category of message | ||
* `source` (`string` or `undefined`, example: `'my-package'`) | ||
β namespace of message | ||
* `ruleId` (`string | null`, example: `'my-rule'`) | ||
### `Options` | ||
Configuration (TypeScript type). | ||
###### Fields | ||
* `ancestors` ([`Array<Node>`][unist-node], optional) | ||
β stack of (inclusive) ancestor nodes surrounding the message | ||
* `cause` ([`Error`][mdn-error], optional) | ||
β original error cause of the message | ||
* `place` ([`Point`][unist-point] or [`Position`][unist-position], optional) | ||
β place of message | ||
* `ruleId` (`string`, optional, example: `'my-rule'`) | ||
β category of message | ||
* `stack` (`string | null`) | ||
β stack of message in code | ||
* `file` (`string | null`) | ||
β path of a file (used throughout the `VFile` ecosystem) | ||
* `source` (`string`, optional, , example: `'my-package'`) | ||
β namespace of who sent the message | ||
@@ -156,10 +171,10 @@ ### Well-known | ||
* `actual` (`string | null`) | ||
* `actual` (`string`, optional) | ||
β specify the source value thatβs being reported, which is deemed incorrect | ||
* `expected` (`Array<string> | null`) | ||
* `expected` (`Array<string>`, optional) | ||
β suggest acceptable values that can be used instead of `actual` | ||
* `url` (`string | null`) | ||
* `url` (`string`, optional) | ||
β link to docs for the message (this must be an absolute URL that can be | ||
passed as `x` to `new URL(x)`) | ||
* `note` (`string | null`) | ||
* `note` (`string`, optional) | ||
β long form description of the message (you should use markdown) | ||
@@ -170,11 +185,14 @@ | ||
This package is fully typed with [TypeScript][]. | ||
It exports no additional types. | ||
It exports the additional type [`Options`][api-options]. | ||
## Compatibility | ||
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-message@^4`, | ||
compatible with Node.js 16. | ||
## Contribute | ||
@@ -208,5 +226,5 @@ | ||
[size-badge]: https://img.shields.io/bundlephobia/minzip/vfile-message.svg | ||
[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=vfile-message | ||
[size]: https://bundlephobia.com/result?p=vfile-message | ||
[size]: https://bundlejs.com/?q=vfile-message | ||
@@ -243,9 +261,9 @@ [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg | ||
[error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error | ||
[mdn-error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error | ||
[node]: https://github.com/syntax-tree/unist#node | ||
[unist-node]: https://github.com/syntax-tree/unist#node | ||
[position]: https://github.com/syntax-tree/unist#position | ||
[unist-point]: https://github.com/syntax-tree/unist#point | ||
[point]: https://github.com/syntax-tree/unist#point | ||
[unist-position]: https://github.com/syntax-tree/unist#position | ||
@@ -256,2 +274,4 @@ [vfile]: https://github.com/vfile/vfile | ||
[api-vfile-message]: #vfilemessagereason-place-origin | ||
[api-options]: #options | ||
[api-vfile-message]: #vfilemessagereason-options |
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
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
24664
11
470
265