https://github.com/wiselibs/super-sources
Beautiful error printing for any source code.
https://github.com/wiselibs/super-sources
Last synced: 8 months ago
JSON representation
Beautiful error printing for any source code.
- Host: GitHub
- URL: https://github.com/wiselibs/super-sources
- Owner: WiseLibs
- License: mit
- Created: 2024-01-10T01:50:58.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2024-01-11T02:31:21.000Z (about 2 years ago)
- Last Synced: 2025-04-14T00:54:26.220Z (9 months ago)
- Language: JavaScript
- Homepage:
- Size: 29.3 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# super-sources [](https://github.com/WiseLibs/super-sources/actions/workflows/test.yml)
This package contains classes for representing pieces of source code, and allows you to print beautiful errors/warnings that display the referenced pieces of source code. Unicode is supported, including the [Supplementary Multilingual Plane](https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane). Windows line terminators (`\r\n`) are also supported.
## Installation
```
npm install super-sources
```
> Requires Node.js v14.x.x or later.
## Usage
```js
const { File, SourceError } = require('super-sources');
const file = new File('example.txt', 'this is a simple file.\nhello worl!\n');
const source = file.at(29, 4); // offset 29, length 4
const error = SourceError.build()
.error('Misspelling detected')
.source(source, 'here')
.note('expected: "world"')
.note(`received: "${source.string()}"`)
.done();
assert(error instanceof Error);
assert(error instanceof SourceError);
console.log(error.print({ colors: false }));
```
Result:
```
Error: Misspelling detected
--> example.txt
|
2 | hello worl!
| ^^^^
* expected: "world"
* received: "worl"
```
# API
## new File(*filename*, *content*)
An object that represents a source file.
```js
const fs = require('fs');
const filename = 'example.txt';
const content = fs.readFileSync(filename, 'utf8');
const file = new File(filename, content);
```
### file.at(*offset*, [*length*]) -> *Source*
Creates a [`Source`](#new-sourcefile-start-end) object, which represents a slice of the source file. If `length` is not provided, it defaults to `1`.
```js
const source = file.at(0);
```
### file.lineNumberAt(*offset*) -> *number*
Returns the line number at the given offset. The first line is `1`.
```js
const lineNumber = file.lineNumberAt(0);
assert(lineNumber === 1);
```
### File properties
- `file.filename`: The filename that was passed to the `File` constructor.
- `file.content`: The content string that was passed to the `File` constructor.
## new Source(*file*, *start*, *end*)
An object that represents a slice of the given [`File`](#new-filefilename-content), from offsets `start` (inclusive) to `end` (exclusive). The length of the slice (`end - start`) must be at least `1`.
```js
const fs = require('fs');
const filename = 'example.txt';
const content = fs.readFileSync(filename, 'utf8');
const file = new File(filename, content);
const source = new Source(file, 0, 1);
```
### source.to(*otherSource*) -> *Source*
Creates a [`Source`](#new-sourcefile-start-end) object that spans the range from this source to another source. A negative or zero-length range will result in a [`RangeError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError). Also, both sources must be from the same file.
```js
const source1 = new Source(file, 0, 5);
const source2 = new Source(file, 3, 8);
const result = source1.to(source2);
assert(result.start === 0);
assert(result.end === 8);
```
### source.string() -> *string*
Returns the original source string represented by this object.
```js
const file = new File('example.txt', 'abcdefg');
const source = new Source(2, 4);
assert(source.string() === 'cd');
```
### source.error(*message*, [*helperText*]) -> *ErrorBuilder*
Shorthand for `SourceError.build().error(message).source(source, helperText)`. See the [`ErrorBuilder`](#class-errorbuilder) class for more details.
```js
source.error('Invalid expression').throw();
```
### source.warning(*message*, [*helperText*]) -> *ErrorBuilder*
Shorthand for `SourceError.build().warning(message).source(source, helperText)`. See the [`ErrorBuilder`](#class-errorbuilder) class for more details.
```js
console.warn(source.warning('Invalid expression').done().print());
```
### Source properties
- `source.file`: The [`File`](#new-filefilename-content) that this source came from.
- `source.start`: The offset where this source slice starts (inclusive).
- `source.end`: The offset where this source slice ends (exclusive).
## class SourceError
A subclass of [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Error) that can reference [`Source`](#new-sourcefile-start-end) objects, and is capable of printing beautiful error messages containing the source code.
Instead of constructing them manually, you can use the static `SourceError.build()` method to conveniently create a new [`ErrorBuilder`](#class-errorbuilder).
```js
const error = SourceError.build()
.error('Misspelling detected')
.source(source, 'here')
.note('expected: "world"')
.note(`received: "${source.string()}"`)
.done();
```
### error.print([*options*]) -> *string*
Returns a string containing a beautifully formatted error message, containing any source code that this error references.
The following options are supported:
- `colors` (boolean)
* Whether or not the output should be colored (by [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)). Default: `true`.
- `filenames` (boolean)
* Whether or not the output should contain the names of the referenced source files. Default: `true`.
- `lineNumbers` (boolean)
* Whether or not the output should contain the line numbers of the referenced source code. Default: `true`.
- `positions` (boolean)
* Whether or not the output should highlight the exact positions of the referenced source code. Default: `true`.
- `maxLines` (number)
* The maximum number of source lines to display (per source snippet) before lines are omitted to save space. Default: `7`.
## class ErrorBuilder
A convenient builder class for making customized [`SourceError`](#class-sourceerror)s.
### builder.error(*message*) -> *this*
Adds an error message to the builder. Any number of error messages can be added.
### builder.warning(*message*) -> *this*
Adds a warning message to the builder. Any number of warning messages can be added.
### builder.source(*source*, [*helperText*]) -> *this*
Adds a [`Source`](#new-sourcefile-start-end) object to the builder. Any number of sources can be added. The added source will be associated with the most recent `.error()` or `.warning()` that was added.
### builder.note(*message*) -> *this*
Adds a note to the builder. Any number of notes can be added. The note will be associated with the most recent `.source()` that was added.
### builder.done() -> *SourceError*
Returns a [`SourceError`](#class-sourceerror) containing all errors, warnings, sources, and notes that were added to this builder.
### builder.throw() -> *throw*
This is the same as `builder.done()`, but the resulting [`SourceError`](#class-sourceerror) will be immediately thrown.
## License
[MIT](https://github.com/WiseLibs/super-sources/blob/master/LICENSE)