Introduce type declaration file for project after updating typescript dependency to 3.7.2.

This commit is contained in:
David Anson 2019-11-10 19:26:55 -08:00
parent 37307d0764
commit 0a9ac73524
9 changed files with 703 additions and 18 deletions

View file

@ -1,3 +1,4 @@
demo/markdown-it.min.js
demo/markdownlint-browser.js
demo/markdownlint-browser.min.js
example/typescript/type-check.js

View file

@ -34,13 +34,13 @@ module.exports = {
};
```
A rule is implemented as an `Object` with four required properties:
A rule is implemented as an `Object` with one optional and four required properties:
- `names` is an `Array` of `String` values that identify the rule in output messages and config.
- `description` is a `String` value that describes the rule in output messages.
- `names` is a required `Array` of `String` values that identify the rule in output messages and config.
- `description` is a required `String` value that describes the rule in output messages.
- `information` is an optional (absolute) `URL` of a link to more information about the rule.
- `tags` is an `Array` of `String` values that groups related rules for easier customization.
- `function` is a synchronous `Function` that implements the rule and is passed two parameters:
- `tags` is a required `Array` of `String` values that groups related rules for easier customization.
- `function` is a required synchronous `Function` that implements the rule and is passed two parameters:
- `params` is an `Object` with properties that describe the content being analyzed:
- `name` is a `String` that identifies the input file/string.
- `tokens` is an `Array` of [`markdown-it` `Token` objects](https://markdown-it.github.io/markdown-it/#Token)
@ -48,7 +48,7 @@ A rule is implemented as an `Object` with four required properties:
- `lines` is an `Array` of `String` values corresponding to the lines of the input file/string.
- `frontMatterLines` is an `Array` of `String` values corresponding to any front matter (not present in `lines`).
- `config` is an `Object` corresponding to the rule's entry in `options.config` (if present).
- `onError` is a function that takes a single `Object` parameter with one required and three optional properties:
- `onError` is a function that takes a single `Object` parameter with one required and four optional properties:
- `lineNumber` is a required `Number` specifying the 1-based line number of the error.
- `details` is an optional `String` with information about what caused the error.
- `context` is an optional `String` with relevant text surrounding the error location.

1
example/typescript/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
type-check.js

View file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"strict": true, /* Enable all strict type-checking options. */
"noUnusedLocals": true, /* Report errors on unused locals. */
"noUnusedParameters": true, /* Report errors on unused parameters. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}

View file

@ -0,0 +1,142 @@
// Attempt to validate all the type declarations in markdownlint.d.ts
import markdownlint from "../..";
const assert = require("assert");
const { URL } = require("url");
const markdownlintJsonPath = "../../.markdownlint.json";
function assertConfiguration(config: markdownlint.Configuration) {
assert(!!config);
assert.equal(config["line-length"], false);
assert.deepEqual(config["no-inline-html"], {
"allowed_elements": [
"a"
]
});
// config assignment is covered by markdownlint.Options
}
function assertConfigurationCallback(err: Error | null, config?: markdownlint.Configuration) {
assert(!err);
config && assertConfiguration(config);
}
function assertLintResults(results: markdownlint.LintResults) {
assert(!!results);
assert.equal(results["string"].length, 1);
assert.equal(results["string"][0].lineNumber, 1);
assert.deepEqual(results["string"][0].ruleNames, [ "MD047", "single-trailing-newline" ]);
assert.equal(results["string"][0].ruleDescription, "Files should end with a single newline character");
assert.equal(results["string"][0].ruleInformation.replace(/v\d+\.\d+\.\d+/, "v0.0.0"), "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md047");
assert.equal(results["string"][0].errorDetail, null);
assert.equal(results["string"][0].errorContext, null);
assert.deepEqual(results["string"][0].errorRange, [ 9, 1 ]);
assert(!!results["string"][0].fixInfo);
assert.equal(results["string"][0].fixInfo.editColumn, 10);
assert(!results["string"][0].fixInfo.deleteCount);
assert.equal(results["string"][0].fixInfo.insertText, "\n");
assert.equal(results["../bad.md"].length, 2);
results = {
"key": [
{
"lineNumber": 1,
"ruleNames": [ "rule", "names" ],
"ruleDescription": "description",
"ruleInformation": "https://example.com/ruleInformation",
"errorDetail": "detail",
"errorContext": "context",
"errorRange": [ 1, 2 ],
"fixInfo": {
"editColumn": 1,
"deleteCount": 1,
"insertText": "text"
}
}
]
};
}
function assertLintResultsCallback(err: Error | null, results?: markdownlint.LintResults) {
assert(!err);
results && assertLintResults(results);
}
assertConfiguration(markdownlint.readConfigSync(markdownlintJsonPath));
assertConfiguration(markdownlint.readConfigSync(markdownlintJsonPath, [ JSON.parse ]));
// The following call is valid, but disallowed because TypeScript does not
// currently propagate {ConfigurationParser[] | null} into the .d.ts file.
// markdownlint.readConfig(markdownlintJsonPath, null, assertConfigCallback);
markdownlint.readConfig(markdownlintJsonPath, [ JSON.parse ], assertConfigurationCallback);
let options: markdownlint.Options;
options = {
"files": [ "../bad.md" ],
"strings": {
"string": "# Heading"
},
"config": {
"no-missing-space-atx": false,
"no-hard-tabs": {
"code_blocks": true
}
},
"customRules": undefined,
"frontMatter": /---/,
"handleRuleFailures": false,
"noInlineConfig": false,
"resultVersion": 3,
"markdownItPlugins": [ [ require("markdown-it-sub") ] ]
};
assertLintResults(markdownlint.sync(options));
markdownlint(options, assertLintResultsCallback);
options.files = "../bad.md";
assertLintResults(markdownlint.sync(options));
markdownlint(options, assertLintResultsCallback);
const testRule = {
"names": [ "test-rule" ],
"description": "Test rule",
"information": new URL("https://example.com/test-rule"),
"tags": [ "test-tag" ],
"function": function rule(params: markdownlint.RuleParams, onError: markdownlint.RuleOnError) {
assert(!!params);
assert(!!onError);
let ruleParams: markdownlint.RuleParams;
ruleParams = {
"name": "name",
"tokens": <markdownlint.MarkdownItToken[]>[],
"lines": [
"one",
"two"
],
"frontMatterLines": [
"three"
],
"config": options.config
};
assert(ruleParams);
let ruleOnErrorInfo: markdownlint.RuleOnErrorInfo;
ruleOnErrorInfo = {
"lineNumber": 1,
"details": "details",
"context": "context",
"range": [ 1, 2 ],
"fixInfo": {
"lineNumber": 1,
"editColumn": 1,
"deleteCount": 1,
"insertText": "text"
}
};
assert(ruleOnErrorInfo);
false && onError(ruleOnErrorInfo);
}
};
options.customRules = [ testRule ];
assertLintResults(markdownlint.sync(options));
markdownlint(options, assertLintResultsCallback);

343
lib/markdownlint.d.ts vendored Normal file
View file

@ -0,0 +1,343 @@
export = markdownlint;
/**
* Lint specified Markdown files.
*
* @param {Options} options Configuration options.
* @param {LintCallback} callback Callback (err, result) function.
* @returns {void}
*/
declare function markdownlint(options: Options, callback: LintCallback): void;
declare namespace markdownlint {
export { markdownlintSync as sync, readConfig, readConfigSync, RuleFunction, RuleParams, MarkdownItToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintCallback, Configuration, RuleConfiguration, ConfigurationParser, ReadConfigCallback };
}
/**
* Configuration options.
*/
type Options = {
/**
* Files to lint.
*/
files?: string | string[];
/**
* Strings to lint.
*/
strings?: {
[x: string]: string;
};
/**
* Configuration object.
*/
config?: {
[x: string]: any;
};
/**
* Custom rules.
*/
customRules?: Rule | Rule[];
/**
* Front matter pattern.
*/
frontMatter?: RegExp;
/**
* True to catch exceptions.
*/
handleRuleFailures?: boolean;
/**
* True to ignore HTML directives.
*/
noInlineConfig?: boolean;
/**
* Results object version.
*/
resultVersion?: number;
/**
* Additional plugins.
*/
markdownItPlugins?: any[][];
};
/**
* Called with the result of the lint operation.
*/
type LintCallback = (err: Error, results?: {
[x: string]: LintError[];
}) => void;
/**
* Lint specified Markdown files synchronously.
*
* @param {Options} options Configuration options.
* @returns {LintResults} Results object.
*/
declare function markdownlintSync(options: Options): {
[x: string]: LintError[];
};
/**
* Read specified configuration file.
*
* @param {string} file Configuration file name.
* @param {ConfigurationParser[] | null} parsers Parsing function(s).
* @param {ReadConfigCallback} callback Callback (err, result) function.
* @returns {void}
*/
declare function readConfig(file: string, parsers: ConfigurationParser[], callback: ReadConfigCallback): void;
/**
* Read specified configuration file synchronously.
*
* @param {string} file Configuration file name.
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
* @returns {Configuration} Configuration object.
*/
declare function readConfigSync(file: string, parsers?: ConfigurationParser[]): {
[x: string]: any;
};
/**
* Function to implement rule logic.
*/
type RuleFunction = (params: RuleParams, onError: RuleOnError) => void;
/**
* Rule parameters.
*/
type RuleParams = {
/**
* File/string name.
*/
name: string;
/**
* markdown-it token objects.
*/
tokens: MarkdownItToken[];
/**
* File/string lines.
*/
lines: string[];
/**
* Front matter lines.
*/
frontMatterLines: string[];
/**
* Rule configuration.
*/
config: any;
};
/**
* Markdown-It token.
*/
type MarkdownItToken = {
/**
* HTML attributes.
*/
attrs: string[][];
/**
* Block-level token.
*/
block: boolean;
/**
* Child nodes.
*/
children: MarkdownItToken[];
/**
* Tag contents.
*/
content: string;
/**
* Ignore element.
*/
hidden: boolean;
/**
* Fence info.
*/
info: string;
/**
* Nesting level.
*/
level: number;
/**
* Beginning/ending line numbers.
*/
map: number[];
/**
* Markup text.
*/
markup: string;
/**
* Arbitrary data.
*/
meta: any;
/**
* Level change.
*/
nesting: number;
/**
* HTML tag name.
*/
tag: string;
/**
* Token type.
*/
type: string;
};
/**
* Error-reporting callback.
*/
type RuleOnError = (onErrorInfo: RuleOnErrorInfo) => void;
/**
* Fix information for RuleOnError callback.
*/
type RuleOnErrorInfo = {
/**
* Line number (1-based).
*/
lineNumber: number;
/**
* Details about the error.
*/
details?: string;
/**
* Context for the error.
*/
context?: string;
/**
* Column number (1-based) and length.
*/
range?: number[];
/**
* Fix information.
*/
fixInfo?: RuleOnErrorFixInfo;
};
/**
* Fix information for RuleOnErrorInfo.
*/
type RuleOnErrorFixInfo = {
/**
* Line number (1-based).
*/
lineNumber?: number;
/**
* Column of the fix (1-based).
*/
editColumn?: number;
/**
* Count of characters to delete.
*/
deleteCount?: number;
/**
* Text to insert (after deleting).
*/
insertText?: string;
};
/**
* Rule definition.
*/
type Rule = {
/**
* Rule name(s).
*/
names: string[];
/**
* Rule description.
*/
description: string;
/**
* Link to more information.
*/
information?: URL;
/**
* Rule tag(s).
*/
tags: string[];
/**
* Rule implementation.
*/
function: RuleFunction;
};
/**
* markdown-it plugin.
*/
type Plugin = any[];
/**
* Function to pretty-print lint results.
*/
type ToStringCallback = (ruleAliases?: boolean) => string;
/**
* Lint results (for resultVersion 3).
*/
type LintResults = {
[x: string]: LintError[];
};
/**
* Lint error.
*/
type LintError = {
/**
* Line number (1-based).
*/
lineNumber: number;
/**
* Rule name(s).
*/
ruleNames: string[];
/**
* Rule description.
*/
ruleDescription: string;
/**
* Link to more information.
*/
ruleInformation: string;
/**
* Detail about the error.
*/
errorDetail: string;
/**
* Context for the error.
*/
errorContext: string;
/**
* Column number (1-based) and length.
*/
errorRange: number[];
/**
* Fix information.
*/
fixInfo: FixInfo;
};
/**
* Fix information.
*/
type FixInfo = {
/**
* Column of the fix (1-based).
*/
editColumn?: number;
/**
* Count of characters to delete.
*/
deleteCount?: number;
/**
* Text to insert (after deleting).
*/
insertText?: string;
};
/**
* Configuration object for linting rules. For a detailed schema, see
* {@link ../schema/markdownlint-config-schema.json}.
*/
type Configuration = {
[x: string]: any;
};
/**
* Rule configuration.
*/
type RuleConfiguration = any;
/**
* Parses a configuration string and returns a configuration object.
*/
type ConfigurationParser = (text: string) => {
[x: string]: any;
};
/**
* Called with the result of the readConfig operation.
*/
type ReadConfigCallback = (err: Error, config?: {
[x: string]: any;
}) => void;

View file

@ -615,8 +615,8 @@ function lintInput(options, synchronous, callback) {
/**
* Lint specified Markdown files.
*
* @param {Object} options Configuration options.
* @param {Function} callback Callback (err, result) function.
* @param {Options} options Configuration options.
* @param {LintCallback} callback Callback (err, result) function.
* @returns {void}
*/
function markdownlint(options, callback) {
@ -626,8 +626,8 @@ function markdownlint(options, callback) {
/**
* Lint specified Markdown files synchronously.
*
* @param {Object} options Configuration options.
* @returns {Object} Result object.
* @param {Options} options Configuration options.
* @returns {LintResults} Results object.
*/
function markdownlintSync(options) {
let results = null;
@ -668,9 +668,9 @@ function parseConfiguration(name, content, parsers) {
/**
* Read specified configuration file.
*
* @param {String} file Configuration file name/path.
* @param {Array} [parsers] Optional parsing function(s).
* @param {Function} callback Callback (err, result) function.
* @param {string} file Configuration file name.
* @param {ConfigurationParser[] | null} parsers Parsing function(s).
* @param {ReadConfigCallback} callback Callback (err, result) function.
* @returns {void}
*/
function readConfig(file, parsers, callback) {
@ -711,9 +711,9 @@ function readConfig(file, parsers, callback) {
/**
* Read specified configuration file synchronously.
*
* @param {String} file Configuration file name/path.
* @param {Array} [parsers] Optional parsing function(s).
* @returns {Object} Configuration object.
* @param {string} file Configuration file name.
* @param {ConfigurationParser[]} [parsers] Parsing function(s).
* @returns {Configuration} Configuration object.
*/
function readConfigSync(file, parsers) {
// Read file
@ -743,3 +743,185 @@ markdownlint.sync = markdownlintSync;
markdownlint.readConfig = readConfig;
markdownlint.readConfigSync = readConfigSync;
module.exports = markdownlint;
// Type declarations
/**
* Function to implement rule logic.
*
* @callback RuleFunction
* @param {RuleParams} params Rule parameters.
* @param {RuleOnError} onError Error-reporting callback.
* @returns {void}
*/
/**
* Rule parameters.
*
* @typedef {Object} RuleParams
* @property {string} name File/string name.
* @property {MarkdownItToken[]} tokens markdown-it token objects.
* @property {string[]} lines File/string lines.
* @property {string[]} frontMatterLines Front matter lines.
* @property {RuleConfiguration} config Rule configuration.
*/
/**
* Markdown-It token.
*
* @typedef {Object} MarkdownItToken
* @property {string[][]} attrs HTML attributes.
* @property {boolean} block Block-level token.
* @property {MarkdownItToken[]} children Child nodes.
* @property {string} content Tag contents.
* @property {boolean} hidden Ignore element.
* @property {string} info Fence info.
* @property {number} level Nesting level.
* @property {number[]} map Beginning/ending line numbers.
* @property {string} markup Markup text.
* @property {Object} meta Arbitrary data.
* @property {number} nesting Level change.
* @property {string} tag HTML tag name.
* @property {string} type Token type.
*/
/**
* Error-reporting callback.
*
* @callback RuleOnError
* @param {RuleOnErrorInfo} onErrorInfo Error information.
* @returns {void}
*/
/**
* Fix information for RuleOnError callback.
*
* @typedef {Object} RuleOnErrorInfo
* @property {number} lineNumber Line number (1-based).
* @property {string} [details] Details about the error.
* @property {string} [context] Context for the error.
* @property {number[]} [range] Column number (1-based) and length.
* @property {RuleOnErrorFixInfo} [fixInfo] Fix information.
*/
/**
* Fix information for RuleOnErrorInfo.
*
* @typedef {Object} RuleOnErrorFixInfo
* @property {number} [lineNumber] Line number (1-based).
* @property {number} [editColumn] Column of the fix (1-based).
* @property {number} [deleteCount] Count of characters to delete.
* @property {string} [insertText] Text to insert (after deleting).
*/
/**
* Rule definition.
*
* @typedef {Object} Rule
* @property {string[]} names Rule name(s).
* @property {string} description Rule description.
* @property {URL} [information] Link to more information.
* @property {string[]} tags Rule tag(s).
* @property {RuleFunction} function Rule implementation.
*/
/**
* Configuration options.
*
* @typedef {Object} Options
* @property {string[] | string} [files] Files to lint.
* @property {Object.<string, string>} [strings] Strings to lint.
* @property {Configuration} [config] Configuration object.
* @property {Rule[] | Rule} [customRules] Custom rules.
* @property {RegExp} [frontMatter] Front matter pattern.
* @property {boolean} [handleRuleFailures] True to catch exceptions.
* @property {boolean} [noInlineConfig] True to ignore HTML directives.
* @property {number} [resultVersion] Results object version.
* @property {Plugin[]} [markdownItPlugins] Additional plugins.
*/
/**
* markdown-it plugin.
*
* @typedef {Array} Plugin
*/
/**
* Function to pretty-print lint results.
*
* @callback ToStringCallback
* @param {boolean} [ruleAliases] True to use rule aliases.
* @returns {string}
*/
/**
* Lint results (for resultVersion 3).
*
* @typedef {Object.<string, LintError[]>} LintResults
*/
// The following should be part of the LintResults typedef, but that causes
// TypeScript to "forget" about the string map.
// * @property {ToStringCallback} toString String representation.
// https://github.com/microsoft/TypeScript/issues/34911
/**
* Lint error.
*
* @typedef {Object} LintError
* @property {number} lineNumber Line number (1-based).
* @property {string[]} ruleNames Rule name(s).
* @property {string} ruleDescription Rule description.
* @property {string} ruleInformation Link to more information.
* @property {string} errorDetail Detail about the error.
* @property {string} errorContext Context for the error.
* @property {number[]} errorRange Column number (1-based) and length.
* @property {FixInfo} fixInfo Fix information.
*/
/**
* Fix information.
*
* @typedef {Object} FixInfo
* @property {number} [editColumn] Column of the fix (1-based).
* @property {number} [deleteCount] Count of characters to delete.
* @property {string} [insertText] Text to insert (after deleting).
*/
/**
* Called with the result of the lint operation.
*
* @callback LintCallback
* @param {Error | null} err Error object or null.
* @param {LintResults} [results] Lint results.
* @returns {void}
*/
/**
* Configuration object for linting rules. For a detailed schema, see
* {@link ../schema/markdownlint-config-schema.json}.
*
* @typedef {Object.<string, RuleConfiguration>} Configuration
*/
/**
* Rule configuration object.
*
* @typedef {boolean | Object} RuleConfiguration Rule configuration.
*/
/**
* Parses a configuration string and returns a configuration object.
*
* @callback ConfigurationParser
* @param {string} text Configuration string.
* @returns {Configuration}
*/
/**
* Called with the result of the readConfig operation.
*
* @callback ReadConfigCallback
* @param {Error | null} err Error object or null.
* @param {Configuration} [config] Configuration object.
* @returns {void}
*/

View file

@ -3,6 +3,7 @@
"version": "0.17.2",
"description": "A Node.js style checker and lint tool for Markdown/CommonMark files.",
"main": "lib/markdownlint.js",
"types": "lib/markdownlint.d.ts",
"author": "David Anson (https://dlaa.me/)",
"license": "MIT",
"homepage": "https://github.com/DavidAnson/markdownlint",
@ -14,11 +15,13 @@
"scripts": {
"test": "nodeunit test/markdownlint-test.js",
"test-cover": "nyc --check-coverage --skip-full node_modules/nodeunit/bin/nodeunit test/markdownlint-test.js",
"test-declaration": "cd example/typescript && tsc && node type-check.js",
"test-extra": "nodeunit test/markdownlint-test-extra.js",
"debug": "node debug node_modules/nodeunit/bin/nodeunit",
"lint": "eslint lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0\" example",
"ci": "npm run test && npm run lint && npm run test-cover",
"ci": "npm run test && npm run lint && npm run test-cover && npm run test-declaration",
"build-config-schema": "node schema/build-config-schema.js",
"build-declaration": "tsc --allowJs --declaration --outDir declaration --resolveJsonModule lib/markdownlint.js && cpy declaration/lib/markdownlint.d.ts lib && rimraf declaration",
"build-demo": "cpy node_modules/markdown-it/dist/markdown-it.min.js demo && cd demo && rimraf markdownlint-browser.* && cpy file-header.js . --rename=markdownlint-browser.js && tsc --allowJs --resolveJsonModule --outDir ../lib-es3 ../lib/markdownlint.js && cpy ../helpers/package.json ../lib-es3/helpers && browserify ../lib-es3/lib/markdownlint.js --standalone markdownlint >> markdownlint-browser.js && uglifyjs markdownlint-browser.js --compress --mangle --comments --output markdownlint-browser.min.js",
"build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2",
"example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint"
@ -46,7 +49,7 @@
"rimraf": "~3.0.0",
"toml": "~3.0.0",
"tv4": "~1.3.0",
"typescript": "~3.6.3",
"typescript": "~3.7.2",
"uglify-js": "~3.6.0"
},
"keywords": [

View file

@ -247,6 +247,7 @@ module.exports.resultFormattingV0 = function resultFormattingV0(test) {
"./test/first_heading_bad_atx.md: 1: MD002" +
" First heading should be a top level heading";
test.equal(actualMessage, expectedMessage, "Incorrect message (name).");
// @ts-ignore
actualMessage = actualResult.toString(true);
expectedMessage =
"./test/atx_heading_spacing.md: 3: first-heading-h1" +
@ -2872,6 +2873,7 @@ module.exports.customRulesV0 = function customRulesV0(test) {
"./test/custom-rules.md: 7: letters-E-X" +
" Rule that reports an error for lines with the letters 'EX'";
test.equal(actualMessage, expectedMessage, "Incorrect message (name).");
// @ts-ignore
actualMessage = actualResult.toString(true);
expectedMessage =
"./test/custom-rules.md: 12: any-blockquote" +