Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

vfile

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vfile - npm Package Compare versions

Comparing version 1.4.0 to 2.0.0

7

history.md

@@ -5,2 +5,9 @@ <!--remark setext-->

2.0.0 / 2016-08-21
==================
* Rewrite interface ([`1959856`](https://github.com/wooorm/vfile/commit/1959856))
* Rewrite `readme.md` ([`dcb86a6`](https://github.com/wooorm/vfile/commit/dcb86a6))
* Refactor code-style to use `xo` ([`019e3fc`](https://github.com/wooorm/vfile/commit/019e3fc))
1.4.0 / 2016-04-18

@@ -7,0 +14,0 @@ ==================

754

index.js

@@ -8,29 +8,3 @@ /**

* information related to processed input. Similar to
* `wearefractal/vinyl`. Additionally, `VFile` can be
* passed directly to ESLint formatters to visualise
* warnings and errors relating to a file.
* @example
* var VFile = require('vfile');
*
* var file = new VFile({
* 'directory': '~',
* 'filename': 'example',
* 'extension': 'txt',
* 'contents': 'Foo *bar* baz'
* });
*
* file.toString(); // 'Foo *bar* baz'
* file.filePath(); // '~/example.txt'
*
* file.move({'extension': 'md'});
* file.filePath(); // '~/example.md'
*
* file.warn('Something went wrong', {'line': 2, 'column': 3});
* // { [~/example.md:2:3: Something went wrong]
* // name: '~/example.md:2:3',
* // file: '~/example.md',
* // reason: 'Something went wrong',
* // line: 2,
* // column: 3,
* // fatal: false }
* `wearefractal/vinyl`.
*/

@@ -40,351 +14,173 @@

/* eslint-env commonjs */
/* Dependencies. */
var path = require('path');
var has = require('has');
var replace = require('replace-ext');
var stringify = require('unist-util-stringify-position');
var buffer = require('is-buffer');
var string = require('x-is-string');
var proto;
/* Expose. */
module.exports = VFile;
var SEPARATOR = '/';
/* Methods. */
var proto = VFile.prototype;
try {
SEPARATOR = require('pa' + 'th').sep;
} catch (e) { /* empty */ }
proto.toString = toString;
proto.message = message;
proto.fail = fail;
/* Slight backwards compatibility. Remove in the future. */
proto.warn = message;
/* Order of setting (least specific to most). */
var order = [
'history',
'path',
'basename',
'stem',
'extname',
'dirname'
];
/**
* Construct a new file message.
* Construct a new file.
*
* Note: We cannot invoke `Error` on the created context,
* as that adds readonly `line` and `column` attributes on
* Safari 9, thus throwing and failing the data.
*
* @example
* var message = new VFileMessage('Whoops!');
*
* message instanceof Error // true
*
* @constructor
* @class {VFileMessage}
* @param {string} reason - Reason for messaging.
* @property {boolean} [fatal=null] - Whether the message
* is fatal.
* @property {string} [name=''] - File-name and positional
* information.
* @property {string} [file=''] - File-path.
* @property {string} [reason=''] - Reason for messaging.
* @property {number} [line=null] - Start of message.
* @property {number} [column=null] - Start of message.
* @property {Position|Location} [location=null] - Place of
* message.
* @property {string} [stack] - Stack-trace of warning.
* @param {Object|VFile|string} [options] - File, contents, or config.
*/
function VFileMessage(reason) {
this.message = reason;
}
function VFile(options) {
var prop;
var index;
var length;
/**
* Inherit from `Error#`.
*/
function VFileMessagePrototype() {}
if (!options) {
options = {};
} else if (string(options) || buffer(options)) {
options = {contents: options};
} else if ('message' in options && 'messages' in options) {
return options;
}
VFileMessagePrototype.prototype = Error.prototype;
if (!(this instanceof VFile)) {
return new VFile(options);
}
proto = new VFileMessagePrototype();
this.data = {};
this.messages = [];
this.history = [];
this.cwd = process.cwd();
VFileMessage.prototype = proto;
/* Set path related properties in the correct order. */
index = -1;
length = order.length;
/*
* Expose defaults.
*/
while (++index < length) {
prop = order[index];
proto.file = proto.name = proto.reason = proto.message = proto.stack = '';
proto.fatal = proto.column = proto.line = null;
if (has(options, prop)) {
this[prop] = options[prop];
}
}
/**
* File-related message with location information.
*
* @typedef {Error} VFileMessage
* @property {string} name - (Starting) location of the
* message, preceded by its file-path when available,
* and joined by `:`. Used internally by the native
* `Error#toString()`.
* @property {string} file - File-path.
* @property {string} reason - Reason for message.
* @property {number?} line - Line of message, when
* available.
* @property {number?} column - Column of message, when
* available.
* @property {string?} stack - Stack of message, when
* available.
* @property {boolean?} fatal - Whether the associated file
* is still processable.
*/
/**
* Stringify a position.
*
* @example
* stringify({'line': 1, 'column': 3}) // '1:3'
* stringify({'line': 1}) // '1:1'
* stringify({'column': 3}) // '1:3'
* stringify() // '1:1'
*
* @private
* @param {Object?} [position] - Single position, like
* those available at `node.position.start`.
* @return {string} - Compiled location.
*/
function stringify(position) {
if (!position) {
position = {};
/* Set non-path related properties. */
for (prop in options) {
if (order.indexOf(prop) === -1) {
this[prop] = options[prop];
}
return (position.line || 1) + ':' + (position.column || 1);
}
}
/**
* ESLint's formatter API expects `filePath` to be a
* string. This hack supports invocation as well as
* implicit coercion.
*
* @example
* var file = new VFile({
* 'filename': 'example',
* 'extension': 'txt'
* });
*
* filePath = filePathFactory(file);
*
* String(filePath); // 'example.txt'
* filePath(); // 'example.txt'
*
* @private
* @param {VFile} file - Virtual file.
* @return {Function} - `filePath` getter.
* Access complete path (`~/index.min.js`).
*/
function filePathFactory(file) {
/**
* Get the filename, with extension and directory, if applicable.
*
* @example
* var file = new VFile({
* 'directory': '~',
* 'filename': 'example',
* 'extension': 'txt'
* });
*
* String(file.filePath); // ~/example.txt
* file.filePath() // ~/example.txt
*
* @memberof {VFile}
* @property {Function} toString - Itself. ESLint's
* formatter API expects `filePath` to be `string`.
* This hack supports invocation as well as implicit
* coercion.
* @return {string} - If the `vFile` has a `filename`,
* it will be prefixed with the directory (slashed),
* if applicable, and suffixed with the (dotted)
* extension (if applicable). Otherwise, an empty
* string is returned.
*/
function filePath() {
var directory = file.directory;
var separator;
Object.defineProperty(proto, 'path', {
get: function () {
return this.history[this.history.length - 1];
},
set: function (path) {
assertNonEmpty(path, 'path');
if (file.filename || file.extension) {
separator = directory.charAt(directory.length - 1);
if (separator === '/' || separator === '\\') {
directory = directory.slice(0, -1);
}
if (directory === '.') {
directory = '';
}
return (directory ? directory + SEPARATOR : '') +
file.filename +
(file.extension ? '.' + file.extension : '');
}
return '';
if (path !== this.path) {
this.history.push(path);
}
}
});
filePath.toString = filePath;
/**
* Access parent path (`~`).
*/
Object.defineProperty(proto, 'dirname', {
get: function () {
return string(this.path) ? path.dirname(this.path) : undefined;
},
set: function (dirname) {
assertPath(this.path, 'dirname');
this.path = path.join(dirname || '', this.basename);
}
});
return filePath;
}
/**
* Get the filename with extantion.
*
* @example
* var file = new VFile({
* 'directory': '~/foo/bar'
* 'filename': 'example',
* 'extension': 'txt'
* });
*
* file.basename() // example.txt
*
* @memberof {VFile}
* @return {string} - name of file with extantion.
*/
function basename() {
var self = this;
var extension = self.extension;
* Access basename (`index.min.js`).
*/
Object.defineProperty(proto, 'basename', {
get: function () {
return string(this.path) ? path.basename(this.path) : undefined;
},
set: function (basename) {
assertNonEmpty(basename, 'basename');
assertPart(basename, 'basename');
this.path = path.join(this.dirname || '', basename);
}
});
if (self.filename || extension) {
return self.filename + (extension ? '.' + extension : '');
}
return '';
}
/**
* Construct a new file.
*
* @example
* var file = new VFile({
* 'directory': '~',
* 'filename': 'example',
* 'extension': 'txt',
* 'contents': 'Foo *bar* baz'
* });
*
* file === VFile(file) // true
* file === new VFile(file) // true
* VFile('foo') instanceof VFile // true
*
* @constructor
* @class {VFile}
* @param {Object|VFile|string} [options] - either an
* options object, or the value of `contents` (both
* optional). When a `file` is passed in, it's
* immediately returned.
* @property {string} [contents=''] - Content of file.
* @property {string} [directory=''] - Path to parent
* directory.
* @property {string} [filename=''] - Filename.
* A file-path can still be generated when no filename
* exists.
* @property {string} [extension=''] - Extension.
* A file-path can still be generated when no extension
* exists.
* @property {boolean?} quiet - Whether an error created by
* `VFile#fail()` is returned (when truthy) or thrown
* (when falsey). Ensure all `messages` associated with
* a file are handled properly when setting this to
* `true`.
* @property {Array.<VFileMessage>} messages - List of associated
* messages.
* Access extname (`.js`).
*/
function VFile(options) {
var self = this;
Object.defineProperty(proto, 'extname', {
get: function () {
return string(this.path) ? path.extname(this.path) : undefined;
},
set: function (extname) {
var ext = extname || '';
/*
* No `new` operator.
*/
assertPart(ext, 'extname');
assertPath(this.path, 'extname');
if (!(self instanceof VFile)) {
return new VFile(options);
}
if (ext) {
if (ext.charAt(0) !== '.') {
throw new Error('`extname` must start with `.`');
}
/*
* Given file.
*/
if (
options &&
typeof options.message === 'function' &&
typeof options.hasFailed === 'function'
) {
return options;
if (ext.indexOf('.', 1) !== -1) {
throw new Error('`extname` cannot contain multiple dots');
}
}
if (!options) {
options = {};
} else if (typeof options === 'string') {
options = {
'contents': options
};
}
this.path = replace(this.path, ext);
}
});
self.contents = options.contents || '';
self.messages = [];
/*
* Make sure eslint’s formatters stringify `filePath`
* properly.
*/
self.filePath = filePathFactory(self);
self.history = [];
self.move({
'filename': options.filename,
'directory': options.directory,
'extension': options.extension
});
}
/**
* Get the value of the file.
*
* @example
* var vFile = new VFile('Foo');
* String(vFile); // 'Foo'
*
* @this {VFile}
* @memberof {VFile}
* @return {string} - value at the `contents` property
* in context.
* Access stem (`index.min`).
*/
function toString() {
return this.contents;
}
Object.defineProperty(proto, 'stem', {
get: function () {
return string(this.path) ? path.basename(this.path, this.extname) : undefined;
},
set: function (stem) {
assertNonEmpty(stem, 'stem');
assertPart(stem, 'stem');
this.path = path.join(this.dirname || '', stem + (this.extname || ''));
}
});
/**
* Move a file by passing a new directory, filename,
* and extension. When these are not given, the default
* values are kept.
* Get the value of the file.
*
* @example
* var file = new VFile({
* 'directory': '~',
* 'filename': 'example',
* 'extension': 'txt',
* 'contents': 'Foo *bar* baz'
* });
*
* file.move({'directory': '/var/www'});
* file.filePath(); // '/var/www/example.txt'
*
* file.move({'extension': 'md'});
* file.filePath(); // '/var/www/example.md'
*
* @this {VFile}
* @memberof {VFile}
* @param {Object?} [options] - Configuration.
* @return {VFile} - Context object.
* @return {string} - Contents.
*/
function move(options) {
var self = this;
var before = self.filePath();
var after;
if (!options) {
options = {};
}
self.directory = options.directory || self.directory || '';
self.filename = options.filename || self.filename || '';
self.extension = options.extension || self.extension || '';
after = self.filePath();
if (after && before !== after) {
self.history.push(after);
}
return self;
function toString(encoding) {
var value = this.contents || '';
return buffer(value) ? value.toString(encoding) : String(value);
}

@@ -397,235 +193,119 @@

*
* @example
* var file = new VFile();
*
* file.message('Something went wrong');
* // { [1:1: Something went wrong]
* // name: '1:1',
* // file: '',
* // reason: 'Something went wrong',
* // line: null,
* // column: null }
*
* @this {VFile}
* @memberof {VFile}
* @param {string|Error} reason - Reason for message.
* @param {Node|Location|Position} [position] - Location
* of message in file.
* @param {string} [ruleId] - Category of warning.
* @return {VFileMessage} - File-related message with
* location information.
* @param {Node|Location|Position} [position] - Place of message.
* @param {string} [ruleId] - Category of message.
* @return {VMessage} - Message.
*/
function message(reason, position, ruleId) {
var filePath = this.filePath();
var range;
var err;
var location = {
'start': {
'line': null,
'column': null
},
'end': {
'line': null,
'column': null
}
};
var filePath = this.path;
var range = stringify(position) || '1:1';
var location;
var err;
/*
* Node / location / position.
*/
location = {
start: {line: null, column: null},
end: {line: null, column: null}
};
if (position && position.position) {
position = position.position;
}
if (position && position.position) {
position = position.position;
}
if (position && position.start) {
range = stringify(position.start) + '-' + stringify(position.end);
location = position;
position = position.start;
if (position) {
/* Location. */
if (position.start) {
location = position;
position = position.start;
} else {
range = stringify(position);
if (position) {
location.start = position;
location.end.line = null;
location.end.column = null;
}
/* Position. */
location.start = position;
location.end.line = null;
location.end.column = null;
}
}
err = new VFileMessage(reason.message || reason);
err = new VMessage(reason.message || reason);
err.name = (filePath ? filePath + ':' : '') + range;
err.file = filePath;
err.reason = reason.message || reason;
err.line = position ? position.line : null;
err.column = position ? position.column : null;
err.location = location;
err.ruleId = ruleId || null;
err.name = (filePath ? filePath + ':' : '') + range;
err.file = filePath || '';
err.reason = reason.message || reason;
err.line = position ? position.line : null;
err.column = position ? position.column : null;
err.location = location;
err.ruleId = ruleId || null;
err.source = null;
err.fatal = false;
if (reason.stack) {
err.stack = reason.stack;
}
if (reason.stack) {
err.stack = reason.stack;
}
return err;
this.messages.push(err);
return err;
}
/**
* Warn. Creates a non-fatal message (see `VFile#message()`),
* and adds it to the file's `messages` list.
* Fail. Creates a vmessage, associates it with the file,
* and throws it.
*
* @example
* var file = new VFile();
*
* file.warn('Something went wrong');
* // { [1:1: Something went wrong]
* // name: '1:1',
* // file: '',
* // reason: 'Something went wrong',
* // line: null,
* // column: null,
* // fatal: false }
*
* @see VFile#message
* @this {VFile}
* @memberof {VFile}
* @throws {VMessage} - Fatal exception.
*/
function warn() {
var err = this.message.apply(this, arguments);
function fail() {
var message = this.message.apply(this, arguments);
err.fatal = false;
message.fatal = true;
this.messages.push(err);
return err;
throw message;
}
/**
* Fail. Creates a fatal message (see `VFile#message()`),
* sets `fatal: true`, adds it to the file's
* `messages` list.
*
* If `quiet` is not `true`, throws the error.
*
* @example
* var file = new VFile();
*
* file.fail('Something went wrong');
* // 1:1: Something went wrong
* // at VFile.exception (vfile/index.js:296:11)
* // at VFile.fail (vfile/index.js:360:20)
* // at repl:1:6
*
* file.quiet = true;
* file.fail('Something went wrong');
* // { [1:1: Something went wrong]
* // name: '1:1',
* // file: '',
* // reason: 'Something went wrong',
* // line: null,
* // column: null,
* // fatal: true }
*
* @this {VFile}
* @memberof {VFile}
* @throws {VFileMessage} - When not `quiet: true`.
* @param {string|Error} reason - Reason for failure.
* @param {Node|Location|Position} [position] - Place
* of failure in file.
* @return {VFileMessage} - Unless thrown, of course.
*/
function fail(reason, position) {
var err = this.message(reason, position);
/* Inherit from `Error#`. */
function VMessagePrototype() {}
VMessagePrototype.prototype = Error.prototype;
VMessage.prototype = new VMessagePrototype();
err.fatal = true;
/* Message properties. */
proto = VMessage.prototype;
this.messages.push(err);
proto.file = proto.name = proto.reason = proto.message = proto.stack = '';
proto.fatal = proto.column = proto.line = null;
if (!this.quiet) {
throw err;
}
return err;
}
/**
* Check if a fatal message occurred making the file no
* longer processable.
* Construct a new file message.
*
* @example
* var file = new VFile();
* file.quiet = true;
* Note: We cannot invoke `Error` on the created context,
* as that adds readonly `line` and `column` attributes on
* Safari 9, thus throwing and failing the data.
*
* file.hasFailed(); // false
*
* file.fail('Something went wrong');
* file.hasFailed(); // true
*
* @this {VFile}
* @memberof {VFile}
* @return {boolean} - `true` if at least one of file's
* `messages` has a `fatal` property set to `true`
* @constructor
* @param {string} reason - Reason for messaging.
*/
function hasFailed() {
var messages = this.messages;
var index = -1;
var length = messages.length;
function VMessage(reason) {
this.message = reason;
}
while (++index < length) {
if (messages[index].fatal) {
return true;
}
}
/* Assert that `part` is not a path (i.e., does
* not contain `path.sep`). */
function assertPart(part, name) {
if (part.indexOf(path.sep) !== -1) {
throw new Error(
'`' + name + '` cannot be a path: did not expect `' + path.sep + '`'
);
}
}
return false;
/* Assert that `part` is not empty. */
function assertNonEmpty(part, name) {
if (!part) {
throw new Error('`' + name + '` cannot be empty');
}
}
/**
* Access metadata.
*
* @example
* var file = new VFile('Foo');
*
* file.namespace('foo').bar = 'baz';
*
* console.log(file.namespace('foo').bar) // 'baz';
*
* @this {VFile}
* @memberof {VFile}
* @param {string} key - Namespace key.
* @return {Object} - Private space.
*/
function namespace(key) {
var self = this;
var space = self.data;
if (!space) {
space = self.data = {};
}
if (!space[key]) {
space[key] = {};
}
return space[key];
/* Assert `path` exists. */
function assertPath(path, name) {
if (!path) {
throw new Error(
'Setting `' + name + '` requires `path` to be set too'
);
}
}
/*
* Methods.
*/
proto = VFile.prototype;
proto.basename = basename;
proto.move = move;
proto.toString = toString;
proto.message = message;
proto.warn = warn;
proto.fail = fail;
proto.hasFailed = hasFailed;
proto.namespace = namespace;
/*
* Expose.
*/
module.exports = VFile;
{
"name": "vfile",
"version": "1.4.0",
"version": "2.0.0",
"description": "Virtual file format for text processing",

@@ -17,7 +17,3 @@ "license": "MIT",

],
"dependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/wooorm/vfile.git"
},
"repository": "https://github.com/wooorm/vfile",
"bugs": "https://github.com/wooorm/vfile/issues",

@@ -28,2 +24,9 @@ "author": "Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)",

],
"dependencies": {
"has": "^1.0.1",
"is-buffer": "^1.1.4",
"replace-ext": "1.0.0",
"unist-util-stringify-position": "^1.0.0",
"x-is-string": "^0.1.0"
},
"files": [

@@ -34,15 +37,12 @@ "index.js"

"browserify": "^13.0.0",
"eslint": "^2.0.0",
"esmangle": "^1.0.0",
"istanbul": "^0.4.0",
"jscs": "^3.0.0",
"jscs-jsdoc": "^2.0.0",
"remark": "^4.0.0",
"remark-comment-config": "^3.0.0",
"remark-github": "^4.0.1",
"remark-lint": "^3.0.0",
"remark-man": "^3.0.0",
"nyc": "^8.1.0",
"remark-cli": "^1.0.0",
"remark-comment-config": "^4.0.0",
"remark-github": "^5.0.0",
"remark-lint": "^4.0.0",
"remark-toc": "^3.0.0",
"remark-validate-links": "^3.0.0",
"tape": "^4.4.0"
"remark-validate-links": "^4.0.0",
"tape": "^4.4.0",
"xo": "^0.16.0"
},

@@ -54,10 +54,45 @@ "scripts": {

"build": "npm run build-md && npm run build-bundle && npm run build-mangle",
"lint-api": "eslint .",
"lint-style": "jscs --reporter inline .",
"lint": "npm run lint-api && npm run lint-style",
"test-api": "node test.js",
"test-coverage": "istanbul cover test.js",
"test-travis": "npm run test-coverage",
"lint": "xo",
"test-api": "node test",
"test-coverage": "nyc --reporter lcov tape test.js",
"test": "npm run build && npm run lint && npm run test-coverage"
},
"nyc": {
"check-coverage": true,
"lines": 100,
"functions": 100,
"branches": 100
},
"xo": {
"space": true,
"rules": {
"guard-for-in": "off",
"max-lines": "off"
},
"ignores": [
"vfile.js",
"vfile.min.js"
]
},
"remarkConfig": {
"output": true,
"plugins": {
"comment-config": null,
"github": null,
"lint": {
"heading-increment": false,
"list-item-spacing": false,
"no-missing-blank-lines": false,
"no-duplicate-headings": false
},
"toc": {
"tight": true,
"maxDepth": 3
},
"validate-links": null
},
"settings": {
"bullet": "*"
}
}
}

@@ -1,26 +0,24 @@

# ![vfile](https://cdn.rawgit.com/wooorm/vfile/master/logo.svg)
# ![vfile][]
[![Build Status](https://img.shields.io/travis/wooorm/vfile.svg)](https://travis-ci.org/wooorm/vfile) [![Coverage Status](https://img.shields.io/codecov/c/github/wooorm/vfile.svg)](https://codecov.io/github/wooorm/vfile)
[![Build Status][build-badge]][build-status]
[![Coverage Status][coverage-badge]][coverage-status]
**VFile** is a virtual file format used by [**retext**](https://github.com/wooorm/retext)
(natural language) and [**remark**](https://github.com/wooorm/remark)
(markdown). Two processors which parse, transform, and compile text. Both need
a virtual representation of files and a place to store metadata and messages.
And, they work in the browser. **VFile** provides these requirements.
> A lot has changed recently, other tools may still use the [1.0.0][]
> API.
Also, **VFile** exposes a warning mechanism compatible with [**ESLint**](https://github.com/eslint/eslint)s
formatters, making it easy to expose [stylish](https://github.com/eslint/eslint/blob/master/lib/formatters/stylish.js)
warnings, or export [tap](https://github.com/eslint/eslint/blob/master/lib/formatters/tap.js)
compliant messages.
**VFile** is a virtual file format used by [**unified**][unified],
a text processing umbrella (it powers [**retext**][retext] for
natural language, [**remark**][remark] for markdown, and
[**rehype**][rehype] for HTML). Each processors that parse, transform,
and compile text, and need a virtual representation of files and a
place to store [messages][] about them. Plus, they work in the browser.
**VFile** provides these requirements at a small size, in IE 9 and up.
> **VFile** is different from (the excellent :+1:) [**vinyl**](https://github.com/wearefractal/vinyl)
> in that it does not include file-system or node-only functionality. No
> buffers, streams, or stats. In addition, the focus on
> [metadata](#vfilenamespacekey) and [messages](#vfilemessagereason-position-ruleid)
> are useful when processing a file through a
> [middleware](https://github.com/segmentio/ware) pipeline.
> **VFile** is different from the excellent [**vinyl**][vinyl]
> in that it has a smaller API, a smaller size, and focusses on
> [messages][].
## Installation
[npm](https://docs.npmjs.com/cli/install):
[npm][]:

@@ -31,33 +29,22 @@ ```bash

**VFile** is also available for [duo](http://duojs.org/#getting-started),
and as an AMD, CommonJS, and globals module, [uncompressed and
compressed](https://github.com/wooorm/vfile/releases).
## Table of Contents
* [Usage](#usage)
* [Related Tools](#related-tools)
* [List of Utilities](#list-of-utilities)
* [API](#api)
* [VFile()](#vfile-1)
* [VFile#contents](#vfilecontents)
* [VFile#directory](#vfiledirectory)
* [VFile#filename](#vfilefilename)
* [VFile#extension](#vfileextension)
* [VFile#basename()](#vfilebasename)
* [VFile#quiet](#vfilequiet)
* [VFile#messages](#vfilemessages)
* [VFile#history](#vfilehistory)
* [VFile#toString()](#vfiletostring)
* [VFile#filePath()](#vfilefilepath)
* [VFile#move(options)](#vfilemoveoptions)
* [VFile#namespace(key)](#vfilenamespacekey)
* [VFile(\[options\])](#vfileoptions)
* [vfile.contents](#vfilecontents)
* [vfile.cwd](#vfilecwd)
* [vfile.path](#vfilepath)
* [vfile.basename](#vfilebasename)
* [vfile.stem](#vfilestem)
* [vfile.extname](#vfileextname)
* [vfile.dirname](#vfiledirname)
* [vfile.history](#vfilehistory)
* [vfile.messages](#vfilemessages)
* [vfile.data](#vfiledata)
* [VFile#toString(\[encoding='utf8'\])](#vfiletostringencodingutf8)
* [VFile#message(reason\[, position\[, ruleId\]\])](#vfilemessagereason-position-ruleid)
* [VFile#warn(reason\[, position\[, ruleId\]\])](#vfilewarnreason-position-ruleid)
* [VFile#fail(reason\[, position\[, ruleId\]\])](#vfilefailreason-position-ruleid)
* [VFile#hasFailed()](#vfilehasfailed)
* [VFileMessage](#vfilemessage)
* [License](#license)

@@ -68,473 +55,230 @@

```js
var VFile = require('vfile');
var vfile = require('vfile');
var file = new VFile({
'directory': '~',
'filename': 'example',
'extension': 'txt',
'contents': 'Foo *bar* baz'
});
var file = vfile({path: '~/example.txt', contents: 'Alpha *braavo* charlie.'});
file.toString(); // 'Foo *bar* baz'
file.filePath(); // '~/example.txt'
console.log(file.path);
// '~/example.txt'
file.move({'extension': 'md'});
file.filePath(); // '~/example.md'
console.log(file.dirname);
// '~'
file.warn('Something went wrong', {'line': 1, 'column': 3});
// { [~/example.md:1:3: Something went wrong]
// name: '~/example.md:1:3',
// file: '~/example.md',
// reason: 'Something went wrong',
file.extname = '.md';
console.log(file.basename);
// 'example.md'
file.basename = 'index.text';
console.log(file.history);
// [ '~/example.txt', '~/example.md', '~/index.text' ]
file.message('`braavo` is misspelt; did you mean `bravo`?', {line: 1, column: 8});
// { [~/index.text:1:8: `braavo` is misspelt; did you mean `bravo`?]
// message: '`braavo` is misspelt; did you mean `bravo`?',
// name: '~/index.text:1:8',
// file: '~/index.text',
// reason: '`braavo` is misspelt; did you mean `bravo`?',
// line: 1,
// column: 3,
// column: 8,
// location:
// { start: { line: 1, column: 8 },
// end: { line: null, column: null } },
// ruleId: null,
// source: null,
// fatal: false }
```
## Related Tools
## List of Utilities
[**VFile**](#api)s are used by both [**retext**](https://github.com/wooorm/retext)
and [**remark**](https://github.com/wooorm/remark).
The following list of projects includes tools for working with virtual
files. See [**Unist**][unist] for projects working with nodes.
In addition, here’s a list of useful tools:
* [`dustinspecker/convert-vinyl-to-vfile`](https://github.com/dustinspecker/convert-vinyl-to-vfile)
— Convert a [Vinyl](https://github.com/wearefractal/vinyl) file to a VFile;
— Convert from [Vinyl][];
* [`shinnn/is-vfile-message`](https://github.com/shinnn/is-vfile-message)
— Check if a value is a `VFileMessage` object;
* [`wooorm/to-vfile`](https://github.com/wooorm/to-vfile)
— Create a virtual file from a file-path;
— Create a virtual file from a file-path (and optionally read it);
* [`wooorm/vfile-find-down`](https://github.com/wooorm/vfile-find-down)
— Find one or more files by searching the file system downwards;
— Find files by searching the file system downwards;
* [`wooorm/vfile-find-up`](https://github.com/wooorm/vfile-find-up)
— Find one or more files by searching the file system upwards;
— Find files by searching the file system upwards;
* [`wooorm/vfile-location`](https://github.com/wooorm/vfile-location)
— Convert between positions (line and column-based) and offsets
(range-based) locations;
— Convert between line/column- and range-based locations;
* [`wooorm/vfile-statistics`](https://github.com/wooorm/vfile-statistics)
— Count messages per category;
* [`shinnn/vfile-messages-to-vscode-diagnostics`](https://github.com/shinnn/vfile-messages-to-vscode-diagnostics)
— Convert `VFileMessage`s into an array of VS Code diagnostics;
— Convert to VS Code diagnostics;
* [`wooorm/vfile-reporter`](https://github.com/wooorm/vfile-reporter)
— Stylish reporter for virtual files.
— Stylish reporter.
* [`wooorm/vfile-sort`](https://github.com/wooorm/vfile-sort)
— Sort virtual file messages by line/column;
— Sort messages by line/column;
* [`sindresorhus/vfile-to-eslint`](https://github.com/sindresorhus/vfile-to-eslint)
— Convert VFiles to ESLint formatter compatible output;
* [`sindresorhus/vfile-reporter-pretty`](https://github.com/sindresorhus/vfile-reporter-pretty)
— Pretty reporter;
## API
### `VFile()`
### `VFile([options])`
**VFile** objects make it easy to move files, to trigger warnings and
errors, and to store supplementary metadata relating to files, all without
accessing the file-system.
Create a new virtual file. If `options` is `string` or `Buffer`, treats
it as `{contents: options}`. If `options` is a `VFile`, returns it.
All other options are set on the newly created `vfile`.
**Example**:
Path related properties are set in the following order (least specific
to most specific): `history`, `path`, `basename`, `stem`, `extname`,
`dirname`.
```js
var file = new VFile({
'directory': '~',
'filename': 'example',
'extension': 'txt',
'contents': 'Foo *bar* baz'
});
It’s not possible to either `dirname` or `extname` without setting
either `history`, `path`, `basename`, or `stem` as well.
file === VFile(file); // true
file === new VFile(file); // true
###### Example
VFile('foo') instanceof VFile; // true
```
**Signatures**:
* `file = VFile(contents|options|vFile?)`.
**Parameters**:
* `contents` (`string`) — Contents of the file;
* `vFile` (`VFile`) — Existing representation, returned without modification;
* `options` (`Object`):
* `directory` (`string?`, default: `''`)
— Parent directory;
* `filename` (`string?`, default: `''`)
— Name, without extension;
* `extension` (`string?`, default: `''`)
— Extension(s), without initial dot;
* `contents` (`string?`, default: `''`)
— Raw value.
**Returns**:
`vFile` — Instance.
**Notes**:
`VFile` exposes an interface compatible with ESLint’s formatters. For example,
to expose warnings using ESLint’s `compact` formatter, execute the following:
```javascript
var compact = require('eslint/lib/formatters/compact');
var VFile = require('vfile');
var vFile = new VFile({
'directory': '~',
'filename': 'hello',
'extension': 'txt'
});
vFile.warn('Whoops, something happened!');
console.log(compact([vFile]));
```
Which would yield the following:
```text
~/hello.txt: line 0, col 0, Warning - Whoops, something happened!
1 problem
```
### `VFile#contents`
`string` — Content of file.
### `VFile#directory`
`string` — Path to parent directory.
### `VFile#filename`
`string` — Filename. A file-path can still be generated when no filename exists.
### `VFile#extension`
`string` — Extension. A file-path can still be generated when no extension
exists.
### `VFile#basename()`
Get the filename, with extension, if applicable.
**Example**:
```js
var file = new VFile({
'directory': '~',
'filename': 'example',
'extension': 'txt'
});
file.basename() // example.txt
vfile();
vfile('console.log("alpha");');
vfile(Buffer.from('exit 1'));
vfile({path: path.join(__dirname, 'readme.md')});
vfile({stem: 'readme', extname: '.md', dirname: __dirname});
vfile({other: 'properties', are: 'copied', ov: {e: 'r'}});
```
**Signatures**:
### `vfile.contents`
* `string = vFile.basename()`.
`Buffer`, `string`, `null` — Raw value.
**Returns**:
### `vfile.cwd`
`string`— Returns the file path without a directory, if applicable.
Otherwise,an empty string is returned.
`string` — Base of `path`. Defaults to `process.cwd()`.
### `VFile#quiet`
### `vfile.path`
`boolean?` — Whether an error created by [`VFile#fail()`](#vfilemessagereason-position-ruleid)
is returned (when truthy) or thrown (when falsey).
`string?` — Path of `vfile`. Cannot be nullified.
Ensure all `messages` associated with a file are handled properly when setting
this to `true`.
### `vfile.basename`
### `VFile#messages`
`string?` — Current name (including extension) of `vfile`. Cannot
contain path separators. Cannot be nullified either (use
`file.path = file.dirname` instead).
`Array.<VFileMessage>` — List of associated messages.
### `vfile.stem`
**Notes**:
`string?` — Name (without extension) of `vfile`. Cannot be nullified,
and cannot contain path separators.
`VFile#message()`, and in turn `VFile#warn()` and `VFile#fail()`, return
`Error` objects that adhere to the [`VFileMessage`](#vfilemessage) schema.
Its results can populate `messages`.
### `vfile.extname`
### `VFile#history`
`string?` — Extension (with dot) of `vfile`. Cannot be set if
there’s no `path` yet and cannot contain path separators.
`Array.<String>` — List of file-paths the file [`move`](#vfilemoveoptions)d
between.
### `vfile.dirname`
### `VFile#toString()`
`string?` — Path to parent directory of `vfile`. Cannot be set if
there’s no `path` yet.
Get the value of the file.
### `vfile.history`
**Example**:
`Array.<string>` — List of file-paths the file moved between.
```js
var vFile = new VFile('Foo');
String(vFile); // 'Foo'
```
### `vfile.messages`
**Signatures**:
`Array.<VFileMessage>` — List of messages associated with the file.
* `string = vFile.toString()`.
### `vfile.data`
**Returns**:
`Object` — Place to store custom information. It’s OK to store custom
data directly on the `vfile`, moving it to `data` gives a _little_ more
privacy.
`string` — Contents.
### `VFile#toString([encoding='utf8'])`
### `VFile#filePath()`
Convert contents of `vfile` to string. If `contents` is a buffer,
`encoding` is used to stringify buffers (default: `'utf8'`).
Get the filename, with extension and directory, if applicable.
**Example**:
```js
var file = new VFile({
'directory': '~',
'filename': 'example',
'extension': 'txt'
});
String(file.filePath); // ~/example.txt
file.filePath() // ~/example.txt
```
**Signatures**:
* `string = vFile.filePath()`.
**Returns**:
`string` — If the `vFile` has a `filename`, it will be prefixed with the
directory (slashed), if applicable, and suffixed with the (dotted) extension
(if applicable). Otherwise, an empty string is returned.
### `VFile#move(options)`
Move a file by passing a new directory, filename, and extension. When these
are not given, the default values are kept.
**Example**:
```js
var file = new VFile({
'directory': '~',
'filename': 'example',
'extension': 'txt',
'contents': 'Foo *bar* baz'
});
file.move({'directory': '/var/www'});
file.filePath(); // '/var/www/example.txt'
file.move({'extension': 'md'});
file.filePath(); // '/var/www/example.md'
```
**Signatures**:
* `vFile = vFile.move(options?)`.
**Parameters**:
* `options` (`Object`):
* `directory` (`string`, default: `''`)
— Parent directory;
* `filename` (`string?`, default: `''`)
— Name, without extension;
* `extension` (`string`, default: `''`)
— Extension(s), without initial dot.
**Returns**:
`vFile` — Context object (chainable).
### `VFile#namespace(key)`
Access metadata.
**Example**:
```js
var file = new VFile('Foo');
file.namespace('foo').bar = 'baz';
console.log(file.namespace('foo').bar) // 'baz';
```
**Parameters**:
* `key` (`string`) — Namespace key.
**Returns**:
`Object` — Private namespace for metadata.
### `VFile#message(reason[, position[, ruleId]])`
Create a message with `reason` at `position`. When an error is passed in as
`reason`, copies the stack. This does not add a message to `messages`.
Associates a message with the file for `reason` at `position`. When an
error is passed in as `reason`, copies the stack.
**Example**:
* `reason` (`string` or `Error`)
— Reason for message, uses the stack and message of the error if given;
* `position` (`Node`, `Location`, or `Position`, optional)
— Place at which the message occurred in `vfile`.
* `ruleId` (`string`, optional)
— Category of warning.
```js
var file = new VFile();
###### Returns
file.message('Something went wrong');
// { [1:1: Something went wrong]
// name: '1:1',
// file: '',
// reason: 'Something went wrong',
// line: null,
// column: null }
```
[`VFileMessage`][message].
**Signatures**:
* `VFileMessage = vFile.message(err|reason, node|location|position?,
ruleId?)`.
**Parameters**:
* `err` (`Error`) — Original error, whose stack and message are used;
* `reason` (`string`) — Reason for message;
* `node` (`Node`) — Syntax tree object;
* `location` (`Object`) — Syntax tree location (found at `node.position`);
* `position` (`Object`) — Syntax tree position (found at
`node.position.start` or `node.position.end`).
* `ruleId` (`string`) — Category of warning.
**Returns**:
[`VFileMessage`](#vfilemessage) — File-related message with location
information.
### `VFile#warn(reason[, position[, ruleId]])`
Warn. Creates a non-fatal message (see [`VFile#message()`](#vfilemessagereason-position-ruleid)),
and adds it to the file's [`messages`](#vfilemessages) list.
**Example**:
```js
var file = new VFile();
file.warn('Something went wrong');
// { [1:1: Something went wrong]
// name: '1:1',
// file: '',
// reason: 'Something went wrong',
// line: null,
// column: null,
// fatal: false }
```
**See**:
* [`VFile#message`](#vfilemessagereason-position-ruleid)
### `VFile#fail(reason[, position[, ruleId]])`
Fail. Creates a fatal message (see `VFile#message()`), sets `fatal: true`,
adds it to the file's `messages` list.
Associates a fatal message with the file, then immediately throws it.
Note: fatal errors mean a file is no longer processable.
Calls [`#message()`][messages] internally.
If `quiet` is not `true`, throws the error.
###### Throws
**Example**:
[`VFileMessage`][message].
```js
var file = new VFile();
### `VFileMessage`
file.fail('Something went wrong');
// 1:1: Something went wrong
// at VFile.exception (vfile/index.js:296:11)
// at VFile.fail (vfile/index.js:360:20)
// at repl:1:6
File-related message describing something at certain position (extends
`Error`).
file.quiet = true;
file.fail('Something went wrong');
// { [1:1: Something went wrong]
// name: '1:1',
// file: '',
// reason: 'Something went wrong',
// line: null,
// column: null,
// fatal: true }
```
###### Properties
**See**:
* `file` (`string`) — File-path (when the message was triggered);
* `reason` (`string`) — Reason for message;
* `ruleId` (`string?`) — Category of message;
* `source` (`string?`) — Namespace of warning;
* `stack` (`string?`) — Stack of message;
* `fatal` (`boolean?`) — If `true`, marks associated file as no longer
processable;
* `line` (`number?`) — Starting line of error;
* `column` (`number?`) — Starting column of error;
* `location` (`object`) — Full range information, when available. Has
`start` and `end` properties, both set to an object with `line` and
`column`, set to `number?`.
* [`VFile#message`](#vfilemessagereason-position-ruleid)
## License
### `VFile#hasFailed()`
[MIT][license] © [Titus Wormer][author]
Check if a fatal message occurred making the file no longer processable.
<!-- Definitions -->
**Example**:
[build-badge]: https://img.shields.io/travis/wooorm/vfile.svg
```js
var file = new VFile();
file.quiet = true;
[build-status]: https://travis-ci.org/wooorm/vfile
file.hasFailed(); // false
[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/vfile.svg
file.fail('Something went wrong');
file.hasFailed(); // true
```
[coverage-status]: https://codecov.io/github/wooorm/vfile
**Signatures**:
[npm]: https://docs.npmjs.com/cli/install
* `boolean = vFile.hasFailed()`.
[license]: LICENSE
**Returns**:
[author]: http://wooorm.com
`boolean` — `true` if at least one of file’s `messages` has a `fatal`
property set to `true`.
[vfile]: https://cdn.rawgit.com/wooorm/vfile/master/logo.svg
### `VFileMessage`
[unified]: https://github.com/wooorm/unified
`Error` — File-related message with location information.
[retext]: https://github.com/wooorm/retext
**Properties**:
[remark]: https://github.com/wooorm/remark
* `name` (`string`)
— (Starting) location of the message, preceded by its file-path when
available, and joined by `':'`. Used by the native
[`Error#toString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name);
[rehype]: https://github.com/wooorm/rehype
* `file` (`string`) — File-path;
[vinyl]: https://github.com/wearefractal/vinyl
* `reason` (`string`) — Reason for message;
[unist]: https://github.com/wooorm/unist#list-of-utilities
* `line` (`number?`) — Line of error, when available;
[messages]: #vfilemessagereason-position-ruleid
* `column` (`number?`) — Column of error, when available;
[message]: #vfilemessage
* `stack` (`string?`) — Stack of message, when available;
* `fatal` (`boolean?`) — Whether the associated file is still processable.
* `location` (`object`) — Full range information, when available. Has
`start` and `end` properties, both set to an object with `line` and
`column`, set to `number?`.
## License
[MIT](LICENSE) © [Titus Wormer](http://wooorm.com)
[1.0.0]: https://github.com/wooorm/vfile/tree/d5abd71
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc