Skip to content

Commit

Permalink
Refactor to move implementation to lib/
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Feb 7, 2023
1 parent 0a9db32 commit 3151230
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 216 deletions.
217 changes: 1 addition & 216 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,216 +1 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Position} Position
* @typedef {import('unist').Point} Point
* @typedef {object & {type: string, position?: Position | undefined}} NodeLike
*/

import {stringifyPosition} from 'unist-util-stringify-position'

export class VFileMessage extends Error {
/**
* Create a message for `reason` at `place` from `origin`.
*
* When an error is passed in as `reason`, the `stack` is copied.
*
* @param {string | Error | VFileMessage} reason
* Reason for message.
* Uses the stack and message of the error if given.
* @param {Node | NodeLike | Position | Point | null | undefined} [place]
* Place at which the message occurred in a file.
* @param {string | null | undefined} [origin]
* Place in code the message originates from (example `'my-package:my-rule-name'`)
*/
// 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}
}

super()

if (typeof place === 'string') {
origin = place
place = undefined
}

if (typeof origin === 'string') {
const index = origin.indexOf(':')

if (index === -1) {
parts[1] = origin
} else {
parts[0] = origin.slice(0, index)
parts[1] = origin.slice(index + 1)
}
}

if (place) {
// Node.
if ('type' in place || 'position' in place) {
if (place.position) {
// @ts-expect-error: looks like a position.
position = place.position
}
}
// Position.
else if ('start' in place || 'end' in place) {
// @ts-expect-error: looks like a position.
position = place
}
// Point.
else if ('line' in place || 'column' in place) {
position.start = place
}
}

// Fields from `Error`.
/**
* Serialized positional info of error.
*
* On normal errors, this would be something like `ParseError`, buit in
* `VFile` messages we use this space to show where an error happened.
*/
this.name = stringifyPosition(place) || '1:1'

/**
* Reason for message.
*
* @type {string}
*/
this.message = typeof reason === 'object' ? reason.message : reason

/**
* 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 = ''

if (typeof reason === 'object' && reason.stack) {
this.stack = reason.stack
}

/**
* Reason for message.
*
* @type {string}
*/
this.reason = this.message

/* eslint-disable no-unused-expressions */
/**
* Whether this is a fatal problem that marks an associated file as no
* longer processable.
*
* If `true`, marks associated file as no longer processable.
* If `false`, necessitates a (potential) change.
* The value can also be `null` or `undefined`, for things that might not
* need changing.
*
* @type {boolean | null | undefined}
*/
this.fatal

/**
* Starting line of error.
*
* @type {number | null}
*/
this.line = position.start.line

/**
* Starting column of error.
*
* @type {number | null}
*/
this.column = position.start.column

/**
* Full range information, when available.
*
* Has `start` and `end` fields, both set to an object with `line` and
* `column`, set to `number | null`.
*
* @type {Position | null}
*/
this.position = position

/**
* Namespace of warning (example: `'my-package'`).
*
* @type {string | null}
*/
this.source = parts[0]

/**
* Category of message (example: `'my-rule-name'`).
*
* @type {string | null}
*/
this.ruleId = parts[1]

/**
* Path of a file (used throughout the `VFile` ecosystem).
*
* @type {string | null}
*/
this.file

// The following fields are “well known”.
// Not standard.
// Feel free to add other non-standard fields to your messages.

/**
* Specify the source value that’s being reported, which is deemed
* incorrect.
*
* @type {string | null}
*/
this.actual

/**
* Suggest values that should be used instead of `actual`, one or more
* values that are deemed as acceptable.
*
* @type {Array<string> | null}
*/
this.expected

/**
* Link to documentation for the message.
*
* @type {string | null}
*/
this.url

/**
* Long form description of the message (supported by `vfile-reporter`).
*
* @type {string | null}
*/
this.note
/* eslint-enable no-unused-expressions */
}
}

VFileMessage.prototype.file = ''
VFileMessage.prototype.name = ''
VFileMessage.prototype.reason = ''
VFileMessage.prototype.message = ''
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
export {VFileMessage} from './lib/index.js'
Loading

0 comments on commit 3151230

Please sign in to comment.