diff --git a/types/vfile/index.d.ts b/types/vfile/index.d.ts index 590fed550ba528..caccb1774add3f 100644 --- a/types/vfile/index.d.ts +++ b/types/vfile/index.d.ts @@ -1,6 +1,7 @@ // Type definitions for VFile 2.2 // Project: https://github.com/vfile/vfile // Definitions by: bizen241 +// Junyoung Choi // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.2 @@ -8,145 +9,167 @@ import * as Unist from 'unist'; -export = VFile; +declare namespace vfile { + type Contents = string | Buffer; -/** - * Create a new virtual file. - * Path related properties are set in the following order (least specific to most specific): `history`, `path`, `basename`, `stem`, `extname`, `dirname`. - * It’s not possible to set either `dirname` or `extname` without setting either `history`, `path`, `basename`, or `stem` as well. - * @param options 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`. - */ -declare function VFile(options?: string | Buffer | Partial): VFile.VFile; - -declare namespace VFile { - interface VFile { + interface NodeWithPosition extends Unist.Node { + position: Unist.Position; [key: string]: any; - /** - * Raw value. - */ - contents: string | Buffer | null; - /** - * Base of `path`. - * Defaults to `process.cwd()`. - */ - cwd: string; - /** - * Path of `vfile`. - * Cannot be nullified. - */ + } + + interface VFileParamsBase { + data?: D; + contents?: Contents; path?: string; - /** - * Current name (including extension) of `vfile`. - * Cannot contain path separators. - * Cannot be nullified either (use `file.path = file.dirname` instead). - */ basename?: string; - /** - * Name (without extension) of `vfile`. - * Cannot be nullified, and cannot contain path separators. - */ stem?: string; - /** - * Extension (with dot) of `vfile`. - * Cannot be set if there's no `path` yet and cannot contain path separators. - */ extname?: string; + dirname?: string; + cwd?: string; + } + + type VFileParams = VFileParamsBase & C; + + /** + * File-related message describing something at certain position. + */ + interface VFileMessage { /** - * Path to parent directory of `vfile`. - * Cannot be set if there's no `path` yet. + * File-path, when the message was triggered. */ - dirname?: string; + file: string; /** - * List of file-paths the file moved between. + * Category of message. */ - history: string[]; + ruleId: string | null; /** - * List of messages associated with the file. + * Reason for message. */ - messages: VFileMessage[]; + reason: string; /** - * 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. + * Starting line of error. */ - data: object; + line: number | null; /** - * Convert contents of `vfile` to string. - * @param encoding If `contents` is a buffer, `encoding` is used to stringify buffers (default: `'utf8'`). + * Starting column of error. */ - toString(encoding?: string): string; + column: number | null; /** - * Associates a message with the file for `reason` at `position`. - * When an error is passed in as `reason`, copies the stack. - * Each message has a `fatal` property which by default is set to `false` (ie. `warning`). - * @param reason Reason for message. Uses the stack and message of the error if given. - * @param position Place at which the message occurred in `vfile`. - * @param ruleId Category of message. + * Full range information, when available. + * Has start and end properties, both set to an object with line and column, set to number?. */ - message(reason: string | Error, position?: Unist.Node | Unist.Point | Unist.Position, ruleId?: string): VFileMessage; + location: Unist.Position; /** - * Associates an informational message with the file, where `fatal` is set to `null`. - * Calls `message()` internally. - * @param reason Reason for message. Uses the stack and message of the error if given. - * @param position Place at which the message occurred in `vfile`. - * @param ruleId Category of message. + * Namespace of warning. */ - info(reason: string | Error, position?: Unist.Node | Unist.Point | Unist.Position, ruleId?: string): VFileMessage; + source: string | null; /** - * Associates a fatal message with the file, then immediately throws it. - * Note: fatal errors mean a file is no longer processable. - * Calls `message()` internally. - * @param reason Reason for message. Uses the stack and message of the error if given. - * @param position Place at which the message occurred in `vfile`. - * @param ruleId Category of message. + * If true, marks associated file as no longer processable. */ - fail(reason: string | Error, position?: Unist.Node | Unist.Point | Unist.Position, ruleId?: string): VFileMessage; + fatal?: boolean | null; } /** - * File-related message describing something at certain position. + * Associates a message with the file for `reason` at `position`. + * When an error is passed in as `reason`, copies the stack. + * Each message has a `fatal` property which by default is set to `false` (ie. `warning`). + * @param reason Reason for message. Uses the stack and message of the error if given. + * @param position Place at which the message occurred in `vfile`. + * @param ruleId Category of message. + */ + type Message = (reason: string, position?: Unist.Point | Unist.Position | NodeWithPosition, ruleId?: string) => VFileMessage; + /** + * Associates a fatal message with the file, then immediately throws it. + * Note: fatal errors mean a file is no longer processable. + * Calls `message()` internally. + * @param reason Reason for message. Uses the stack and message of the error if given. + * @param position Place at which the message occurred in `vfile`. + * @param ruleId Category of message. + */ + type Fail = (reason: string, position?: Unist.Point | Unist.Position | NodeWithPosition, ruleId?: string) => never; + /** + * Associates an informational message with the file, where `fatal` is set to `null`. + * Calls `message()` internally. + * @param reason Reason for message. Uses the stack and message of the error if given. + * @param position Place at which the message occurred in `vfile`. + * @param ruleId Category of message. + */ + type Info = (reason: string, position?: Unist.Point | Unist.Position | NodeWithPosition, ruleId?: string) => void; + + /** + * Convert contents of `vfile` to string. + * @param encoding If `contents` is a buffer, `encoding` is used to stringify buffers (default: `'utf8'`). */ - interface VFileMessage extends Error { + type ToString = (encoding?: BufferEncoding) => string; + + interface VFileBase { /** - * File-path, when the message was triggered. + * @param options 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`. */ - file: string; + (input?: Contents): VFile; + (input?: VFile | VFileParams): VFile; + message: Message; + fail: Fail; + info: Info; /** - * Reason for message. + * List of file-paths the file moved between. */ - reason: string; + history: string[]; /** - * Category of message. + * 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. */ - ruleId: string | null; + data: C['data']; /** - * Namespace of warning. + * List of messages associated with the file. */ - source: string | null; + messages: VFileMessage[]; /** - * If true, marks associated file as no longer processable. + * Raw value. */ - fatal: boolean | null; + contents: Contents; /** - * Starting line of error. + * Path of `vfile`. + * Cannot be nullified. */ - line: number | null; + path?: string; /** - * Starting column of error. + * Path to parent directory of `vfile`. + * Cannot be set if there's no `path` yet. */ - column: number | null; + dirname?: string; /** - * Full range information, when available. - * Has start and end properties, both set to an object with line and column, set to number?. + * Current name (including extension) of `vfile`. + * Cannot contain path separators. + * Cannot be nullified either (use `file.path = file.dirname` instead). + */ + basename?: string; + /** + * Name (without extension) of `vfile`. + * Cannot be nullified, and cannot contain path separators. + */ + stem?: string; + /** + * Extension (with dot) of `vfile`. + * Cannot be set if there's no `path` yet and cannot contain path separators. + */ + extname?: string; + /** + * Base of `path`. + * Defaults to `process.cwd()`. */ - location: { - start: { - line: number | null; - column: number | null; - }; - end: { - line: number | null; - column: number | null; - }; - }; + cwd: string; + toString: ToString; } + + type VFile = VFileBase & C; } + +/** + * Create a new virtual file. + * Path related properties are set in the following order (least specific to most specific): `history`, `path`, `basename`, `stem`, `extname`, `dirname`. + * It’s not possible to set either `dirname` or `extname` without setting either `history`, `path`, `basename`, or `stem` as well. + */ +declare const vfile: vfile.VFile<{}>; + +export = vfile; diff --git a/types/vfile/tsconfig.json b/types/vfile/tsconfig.json index 7615c6e59ac487..af04818380bf10 100644 --- a/types/vfile/tsconfig.json +++ b/types/vfile/tsconfig.json @@ -17,6 +17,7 @@ }, "files": [ "index.d.ts", + "vfile-tests.ts" ] } diff --git a/types/vfile/vfile-tests.ts b/types/vfile/vfile-tests.ts index aae566154bc214..0b19246ae87899 100644 --- a/types/vfile/vfile-tests.ts +++ b/types/vfile/vfile-tests.ts @@ -1,6 +1,7 @@ -import * as vfile from 'vfile'; +import vfile = require("vfile"); import * as Unist from 'unist'; +// Instantiation vfile(); vfile('string'); vfile(Buffer.from('string')); @@ -13,35 +14,58 @@ try { console.log('Error: set extname without path'); } -const file: vfile.VFile = vfile({ contents: 'contents' }); +const file = vfile<{custom: string, data: {custom: number}}>({ + path: '~/example.txt', + contents: 'Alpha *braavo* charlie.', + custom: 'Custom tango', + data: { + custom: 12345 + }, +}); + +file.path; // => '~/example.txt' +file.dirname; // => '~' -file.path = '~/readme.txt'; -file.basename = 'example.txt'; -file.stem = 'readme'; file.extname = '.md'; -file.data = { - key: 'value', -}; -const history: string[] = file.history; -const contents: string = file.toString(); +file.basename; // => 'example.md' + +file.basename = 'index.text'; + +file.history; // => ['~/example.txt', '~/example.md', '~/index.text'] + +file.message('`braavo` is misspelt; did you mean `bravo`?', {line: 1, column: 8}); + +console.log(file.messages); -console.log('file.history =>', history); -console.log('file.contents =>', contents); +// Typings of the custom data can be resolved from the parameters above +const custom: string = file.custom; // 'Custom tango' +const dataCustom: number = file.data.custom; // 12345 -const position: Unist.Point = { +// message method accept any Stringifiable Position(e.g. point, position, node with position) +const startPoint: Unist.Point = { line: 1, column: 1, }; +const position: Unist.Position = { + start: startPoint, + end: { + line: 2, + column: 2, + }, +}; +// Accept Point +file.message('test', startPoint); +// Accept Position +file.message('test', position); +// Accept Node with extra value +file.message('test', { + type: 'ramdom node', + position, + extraValue: 'extra tango', +}); +// But, it must reject any malformed position +file.message('test', { start: 'invalid point' }); // $ExpectError -file.message('reason', position); -file.info('reason', position); -try { - file.fail('reason', position); -} catch (e) { - console.log('Error: associated a fatal message'); -} - -const messages: vfile.VFileMessage[] = file.messages; - -console.log('file.messages =>', messages); +// Typings of original properties must be kept +const fileWithWrongParams = vfile({ path: 1234 }); // $ExpectError