markdownlint-cli2 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +83 -35
- package/constants.mjs +30 -0
- package/markdownlint-cli2.mjs +216 -243
- package/package.json +25 -21
- package/parsers/parsers.mjs +2 -0
- package/parsers/toml-parse.mjs +11 -0
- package/schema/markdownlint-cli2-config-schema.json +15 -15
package/markdownlint-cli2.mjs
CHANGED
|
@@ -7,22 +7,22 @@ import pathDefault from "node:path";
|
|
|
7
7
|
const pathPosix = pathDefault.posix;
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
9
9
|
import { globby } from "globby";
|
|
10
|
+
import jsonpointer from "jsonpointer";
|
|
10
11
|
import micromatch from "micromatch";
|
|
11
12
|
import { applyFixes, getVersion, resolveModule } from "markdownlint";
|
|
12
13
|
import { lint, extendConfig, readConfig } from "markdownlint/promise";
|
|
13
14
|
import { expandTildePath } from "markdownlint/helpers";
|
|
14
15
|
import appendToArray from "./append-to-array.mjs";
|
|
16
|
+
import { cli2SchemaKeys, libraryName, packageName, packageVersion } from "./constants.mjs";
|
|
15
17
|
import mergeOptions from "./merge-options.mjs";
|
|
16
|
-
import
|
|
18
|
+
import allParsers from "./parsers/parsers.mjs";
|
|
17
19
|
import jsoncParse from "./parsers/jsonc-parse.mjs";
|
|
20
|
+
import tomlParse from "./parsers/toml-parse.mjs";
|
|
18
21
|
import yamlParse from "./parsers/yaml-parse.mjs";
|
|
19
22
|
|
|
20
23
|
/* eslint-disable jsdoc/reject-any-type */
|
|
21
24
|
|
|
22
25
|
// Variables
|
|
23
|
-
const packageName = "markdownlint-cli2";
|
|
24
|
-
const packageVersion = "0.20.0";
|
|
25
|
-
const libraryName = "markdownlint";
|
|
26
26
|
const libraryVersion = getVersion();
|
|
27
27
|
const bannerMessage = `${packageName} v${packageVersion} (${libraryName} v${libraryVersion})`;
|
|
28
28
|
const dotOnlySubstitute = "*.{md,markdown}";
|
|
@@ -34,6 +34,15 @@ const noop = () => null;
|
|
|
34
34
|
// Negates a glob
|
|
35
35
|
const negateGlob = (/** @type {string} */ glob) => `!${glob}`;
|
|
36
36
|
|
|
37
|
+
// Reads and parses a JSONC file
|
|
38
|
+
const readJsonc = (/** @type {string} */ file, /** @type {FsLike} */ fs) => fs.promises.readFile(file, utf8).then(jsoncParse);
|
|
39
|
+
|
|
40
|
+
// Reads and parses a TOML file
|
|
41
|
+
const readToml = (/** @type {string} */ file, /** @type {FsLike} */ fs) => fs.promises.readFile(file, utf8).then(tomlParse);
|
|
42
|
+
|
|
43
|
+
// Reads and parses a YAML file
|
|
44
|
+
const readYaml = (/** @type {string} */ file, /** @type {FsLike} */ fs) => fs.promises.readFile(file, utf8).then(yamlParse);
|
|
45
|
+
|
|
37
46
|
// Throws a meaningful exception for an unusable configuration file
|
|
38
47
|
const throwForConfigurationFile = (/** @type {string} */ file, /** @type {Error | any} */ error) => {
|
|
39
48
|
throw new Error(
|
|
@@ -50,20 +59,6 @@ const resolveModulePaths = (/** @type {string} */ dir, /** @type {string[]} */ m
|
|
|
50
59
|
modulePaths.map((path) => pathDefault.resolve(dir, expandTildePath(path, os)))
|
|
51
60
|
);
|
|
52
61
|
|
|
53
|
-
// Read a JSON(C) or YAML file and return the object
|
|
54
|
-
const readConfigFile = (/** @type {FsLike} */ fs, /** @type {string} */ dir, /** @type {string} */ name, /** @type {() => void} */ otherwise) => () => {
|
|
55
|
-
const file = pathPosix.join(dir, name);
|
|
56
|
-
return fs.promises.access(file).
|
|
57
|
-
then(
|
|
58
|
-
() => readConfig(
|
|
59
|
-
file,
|
|
60
|
-
parsers,
|
|
61
|
-
fs
|
|
62
|
-
),
|
|
63
|
-
otherwise
|
|
64
|
-
);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
62
|
// Import a module ID with a custom directory in the path
|
|
68
63
|
const importModule = async (/** @type {string[] | string} */ dirOrDirs, /** @type {string} */ id, /** @type {boolean} */ noImport) => {
|
|
69
64
|
if (typeof id !== "string") {
|
|
@@ -118,19 +113,10 @@ const importModuleIdsAndParams = (/** @type {string[]} */ dirs, /** @type {strin
|
|
|
118
113
|
).then((results) => results.filter(Boolean))
|
|
119
114
|
);
|
|
120
115
|
|
|
121
|
-
// Import a JavaScript file and return the exported object
|
|
122
|
-
const importConfig = (/** @type {FsLike} */ fs, /** @type {string} */ dir, /** @type {string} */ name, /** @type {boolean} */ noImport, /** @type {() => void} */ otherwise) => () => {
|
|
123
|
-
const file = pathPosix.join(dir, name);
|
|
124
|
-
return fs.promises.access(file).
|
|
125
|
-
then(
|
|
126
|
-
() => importModule(dir, name, noImport),
|
|
127
|
-
otherwise
|
|
128
|
-
);
|
|
129
|
-
};
|
|
130
|
-
|
|
131
116
|
// Extend a config object if it has 'extends' property
|
|
132
|
-
const getExtendedConfig = (/** @type {
|
|
117
|
+
const getExtendedConfig = (/** @type {ExecutionContext} */ context, /** @type {Configuration} */ config, /** @type {string} */ configPath) => {
|
|
133
118
|
if (config.extends) {
|
|
119
|
+
const { fs, parsers } = context;
|
|
134
120
|
return extendConfig(
|
|
135
121
|
config,
|
|
136
122
|
configPath,
|
|
@@ -143,50 +129,64 @@ const getExtendedConfig = (/** @type {import("markdownlint").Configuration} */ c
|
|
|
143
129
|
};
|
|
144
130
|
|
|
145
131
|
// Read an options or config file in any format and return the object
|
|
146
|
-
const readOptionsOrConfig = async (/** @type {
|
|
132
|
+
const readOptionsOrConfig = async (/** @type {ExecutionContext} */ context, /** @type {string} */ configPath, /** @type {string | undefined} */ configPointer) => {
|
|
133
|
+
const { fs, noImport } = context;
|
|
147
134
|
const basename = pathPosix.basename(configPath);
|
|
148
135
|
const dirname = pathPosix.dirname(configPath);
|
|
149
136
|
let options = null;
|
|
150
137
|
let config = null;
|
|
138
|
+
let unknown = null;
|
|
151
139
|
try {
|
|
152
140
|
if (basename.endsWith(".markdownlint-cli2.jsonc")) {
|
|
153
|
-
options =
|
|
141
|
+
options = await readJsonc(configPath, fs);
|
|
154
142
|
} else if (basename.endsWith(".markdownlint-cli2.yaml")) {
|
|
155
|
-
options =
|
|
156
|
-
} else if (
|
|
157
|
-
basename.endsWith(".markdownlint-cli2.cjs") ||
|
|
158
|
-
basename.endsWith(".markdownlint-cli2.mjs")
|
|
159
|
-
) {
|
|
143
|
+
options = await readYaml(configPath, fs);
|
|
144
|
+
} else if (basename.endsWith(".markdownlint-cli2.cjs") || basename.endsWith(".markdownlint-cli2.mjs")) {
|
|
160
145
|
options = await importModule(dirname, basename, noImport);
|
|
161
|
-
} else if (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
) {
|
|
167
|
-
config = await readConfig(configPath, parsers, fs);
|
|
168
|
-
} else if (
|
|
169
|
-
basename.endsWith(".markdownlint.cjs") ||
|
|
170
|
-
basename.endsWith(".markdownlint.mjs")
|
|
171
|
-
) {
|
|
146
|
+
} else if (basename.endsWith(".markdownlint.jsonc") || basename.endsWith(".markdownlint.json")) {
|
|
147
|
+
config = await readJsonc(configPath, fs);
|
|
148
|
+
} else if (basename.endsWith(".markdownlint.yaml") || basename.endsWith(".markdownlint.yml")) {
|
|
149
|
+
config = await readYaml(configPath, fs);
|
|
150
|
+
} else if (basename.endsWith(".markdownlint.cjs") || basename.endsWith(".markdownlint.mjs")) {
|
|
172
151
|
config = await importModule(dirname, basename, noImport);
|
|
152
|
+
} else if (basename.endsWith(".jsonc") || basename.endsWith(".json")) {
|
|
153
|
+
unknown = await readJsonc(configPath, fs);
|
|
154
|
+
} else if (basename.endsWith(".toml")) {
|
|
155
|
+
unknown = await readToml(configPath, fs);
|
|
156
|
+
} else if (basename.endsWith(".yaml") || basename.endsWith(".yml")) {
|
|
157
|
+
unknown = await readYaml(configPath, fs);
|
|
158
|
+
} else if (basename.endsWith(".cjs") || basename.endsWith(".mjs")) {
|
|
159
|
+
unknown = await importModule(dirname, basename, noImport);
|
|
173
160
|
} else {
|
|
174
161
|
throw new Error(
|
|
175
162
|
"Configuration file should be one of the supported names " +
|
|
176
163
|
"(e.g., '.markdownlint-cli2.jsonc') or a prefix with a supported name " +
|
|
177
|
-
"(e.g., 'example.markdownlint-cli2.jsonc')
|
|
164
|
+
"(e.g., 'example.markdownlint-cli2.jsonc') or have a supported extension " +
|
|
165
|
+
"(e.g., jsonc, json, yaml, yml, cjs, mjs)."
|
|
178
166
|
);
|
|
179
167
|
}
|
|
180
168
|
} catch (error) {
|
|
181
169
|
throwForConfigurationFile(configPath, error);
|
|
182
170
|
}
|
|
171
|
+
if (configPointer) {
|
|
172
|
+
const objects = [ options, config, unknown ];
|
|
173
|
+
[ options, config, unknown ] = objects.map((obj) => obj && (jsonpointer.get(obj, configPointer) || {}));
|
|
174
|
+
}
|
|
175
|
+
if (unknown) {
|
|
176
|
+
const keys = Object.keys(unknown);
|
|
177
|
+
if (keys.some((key) => cli2SchemaKeys.has(key))) {
|
|
178
|
+
options = unknown;
|
|
179
|
+
} else {
|
|
180
|
+
config = unknown;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
183
|
if (options) {
|
|
184
184
|
if (options.config) {
|
|
185
|
-
options.config = await getExtendedConfig(options.config, configPath
|
|
185
|
+
options.config = await getExtendedConfig(context, options.config, configPath);
|
|
186
186
|
}
|
|
187
187
|
return options;
|
|
188
188
|
}
|
|
189
|
-
config = await getExtendedConfig(config, configPath
|
|
189
|
+
config = await getExtendedConfig(context, config, configPath);
|
|
190
190
|
return { config };
|
|
191
191
|
};
|
|
192
192
|
|
|
@@ -229,7 +229,7 @@ const showHelp = (/** @type {Logger} */ logMessage, /** @type {boolean} */ showB
|
|
|
229
229
|
}
|
|
230
230
|
logMessage(`https://github.com/DavidAnson/markdownlint-cli2
|
|
231
231
|
|
|
232
|
-
Syntax: markdownlint-cli2 glob0 [glob1] [...] [globN] [--config file] [--fix] [--format] [--help] [--no-globs]
|
|
232
|
+
Syntax: markdownlint-cli2 glob0 [glob1] [...] [globN] [--config file] [--configPointer pointer] [--fix] [--format] [--help] [--no-globs]
|
|
233
233
|
|
|
234
234
|
Glob expressions (from the globby library):
|
|
235
235
|
- * matches any number of characters, but not /
|
|
@@ -246,11 +246,12 @@ Dot-only glob:
|
|
|
246
246
|
- To lint every file in the current directory tree, the command "markdownlint-cli2 **" can be used instead
|
|
247
247
|
|
|
248
248
|
Optional parameters:
|
|
249
|
-
- --config
|
|
250
|
-
- --
|
|
251
|
-
- --
|
|
252
|
-
- --
|
|
253
|
-
- --
|
|
249
|
+
- --config specifies the path to a configuration file to define the base configuration
|
|
250
|
+
- --configPointer specifies a JSON Pointer to a configuration object within the --config file
|
|
251
|
+
- --fix updates files to resolve fixable issues (can be overridden in configuration)
|
|
252
|
+
- --format reads standard input (stdin), applies fixes, writes standard output (stdout)
|
|
253
|
+
- --help writes this message to the console and exits without doing anything else
|
|
254
|
+
- --no-globs ignores the "globs" property if present in the top-level options object
|
|
254
255
|
|
|
255
256
|
Configuration via:
|
|
256
257
|
- .markdownlint-cli2.jsonc
|
|
@@ -259,7 +260,6 @@ Configuration via:
|
|
|
259
260
|
- .markdownlint.jsonc or .markdownlint.json
|
|
260
261
|
- .markdownlint.yaml or .markdownlint.yml
|
|
261
262
|
- .markdownlint.cjs or .markdownlint.mjs
|
|
262
|
-
- package.json
|
|
263
263
|
|
|
264
264
|
Cross-platform compatibility:
|
|
265
265
|
- UNIX and Windows shells expand globs according to different rules; quoting arguments is recommended
|
|
@@ -275,15 +275,61 @@ $ markdownlint-cli2 "**/*.md" "#node_modules"`
|
|
|
275
275
|
return 2;
|
|
276
276
|
};
|
|
277
277
|
|
|
278
|
+
// Helpers for getAndProcessDirInfo/handleFirstMatchingConfigurationFile
|
|
279
|
+
const readJsoncWrapper = (/** @type {ConfigurationHandlerParams} */ { file, fs }) => readJsonc(file, fs);
|
|
280
|
+
const readYamlWrapper = (/** @type {ConfigurationHandlerParams} */ { file, fs }) => readYaml(file, fs);
|
|
281
|
+
const readConfigWrapper = (/** @type {ConfigurationHandlerParams} */ { file, fs, parsers }) => readConfig(file, parsers, fs);
|
|
282
|
+
const importModuleWrapper = (/** @type {ConfigurationHandlerParams} */ { dir, file, noImport }) => importModule(dir, file, noImport);
|
|
283
|
+
|
|
284
|
+
/** @type {ConfigurationFileAndHandler[] } */
|
|
285
|
+
const optionsFiles = [
|
|
286
|
+
[ ".markdownlint-cli2.jsonc", readJsoncWrapper ],
|
|
287
|
+
[ ".markdownlint-cli2.yaml", readYamlWrapper ],
|
|
288
|
+
[ ".markdownlint-cli2.cjs", importModuleWrapper ],
|
|
289
|
+
[ ".markdownlint-cli2.mjs", importModuleWrapper ]
|
|
290
|
+
];
|
|
291
|
+
|
|
292
|
+
/** @type {ConfigurationFileAndHandler[] } */
|
|
293
|
+
const configurationFiles = [
|
|
294
|
+
[ ".markdownlint.jsonc", readConfigWrapper ],
|
|
295
|
+
[ ".markdownlint.json", readConfigWrapper ],
|
|
296
|
+
[ ".markdownlint.yaml", readConfigWrapper ],
|
|
297
|
+
[ ".markdownlint.yml", readConfigWrapper ],
|
|
298
|
+
[ ".markdownlint.cjs", importModuleWrapper ],
|
|
299
|
+
[ ".markdownlint.mjs", importModuleWrapper ]
|
|
300
|
+
];
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Processes the first matching configuration file.
|
|
304
|
+
* @param {ExecutionContext} context Execution context.
|
|
305
|
+
* @param {ConfigurationFileAndHandler[]} fileAndHandlers List of configuration files and handlers.
|
|
306
|
+
* @param {string} dir Configuration file directory.
|
|
307
|
+
* @param {(file: string) => void} memoizeFile Function to memoize file name.
|
|
308
|
+
* @returns {Promise<any>} Configuration file content.
|
|
309
|
+
*/
|
|
310
|
+
const processFirstMatchingConfigurationFile = (context, fileAndHandlers, dir, memoizeFile) => {
|
|
311
|
+
const { fs, noImport, parsers } = context;
|
|
312
|
+
return Promise.allSettled(
|
|
313
|
+
fileAndHandlers.map(([ name, handler ]) => {
|
|
314
|
+
const file = pathPosix.join(dir, name);
|
|
315
|
+
return fs.promises.access(file).then(() => [ file, handler ]);
|
|
316
|
+
})
|
|
317
|
+
).
|
|
318
|
+
then((values) => {
|
|
319
|
+
/** @type {ConfigurationFileAndHandler} */
|
|
320
|
+
const [ file, handler ] = values.find((result) => (result.status === "fulfilled"))?.value || [ "[UNUSED]", noop ];
|
|
321
|
+
memoizeFile(file);
|
|
322
|
+
return handler({ dir, file, fs, noImport, parsers });
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
|
|
278
326
|
// Get (creating if necessary) and process a directory's info object
|
|
279
327
|
const getAndProcessDirInfo = (
|
|
280
|
-
/** @type {
|
|
328
|
+
/** @type {ExecutionContext} */ context,
|
|
281
329
|
/** @type {Task[]} */ tasks,
|
|
282
330
|
/** @type {DirToDirInfo} */ dirToDirInfo,
|
|
283
331
|
/** @type {string} */ dir,
|
|
284
|
-
/** @type {string | null} */ relativeDir
|
|
285
|
-
/** @type {boolean} */ noImport,
|
|
286
|
-
/** @type {boolean} */ allowPackageJson
|
|
332
|
+
/** @type {string | null} */ relativeDir
|
|
287
333
|
) => {
|
|
288
334
|
// Create dirInfo
|
|
289
335
|
let dirInfo = dirToDirInfo[dir];
|
|
@@ -293,106 +339,37 @@ const getAndProcessDirInfo = (
|
|
|
293
339
|
relativeDir,
|
|
294
340
|
"parent": null,
|
|
295
341
|
"files": [],
|
|
296
|
-
"markdownlintConfig":
|
|
297
|
-
"markdownlintOptions":
|
|
342
|
+
"markdownlintConfig": null,
|
|
343
|
+
"markdownlintOptions": null
|
|
298
344
|
};
|
|
299
345
|
dirToDirInfo[dir] = dirInfo;
|
|
300
346
|
|
|
301
|
-
|
|
302
|
-
const markdownlintCli2Jsonc = pathPosix.join(dir, ".markdownlint-cli2.jsonc");
|
|
303
|
-
const markdownlintCli2Yaml = pathPosix.join(dir, ".markdownlint-cli2.yaml");
|
|
304
|
-
const markdownlintCli2Cjs = pathPosix.join(dir, ".markdownlint-cli2.cjs");
|
|
305
|
-
const markdownlintCli2Mjs = pathPosix.join(dir, ".markdownlint-cli2.mjs");
|
|
306
|
-
const packageJson = pathPosix.join(dir, "package.json");
|
|
307
|
-
let file = "[UNKNOWN]";
|
|
308
|
-
// eslint-disable-next-line no-return-assign
|
|
309
|
-
const captureFile = (/** @type {string} */ f) => file = f;
|
|
347
|
+
let cli2File = "[UNKNOWN]";
|
|
310
348
|
tasks.push(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
then(
|
|
316
|
-
() => fs.promises.readFile(file, utf8).then(yamlParse),
|
|
317
|
-
() => fs.promises.access(captureFile(markdownlintCli2Cjs)).
|
|
318
|
-
then(
|
|
319
|
-
() => importModule(dir, file, noImport),
|
|
320
|
-
() => fs.promises.access(captureFile(markdownlintCli2Mjs)).
|
|
321
|
-
then(
|
|
322
|
-
() => importModule(dir, file, noImport),
|
|
323
|
-
() => (allowPackageJson
|
|
324
|
-
? fs.promises.access(captureFile(packageJson))
|
|
325
|
-
// eslint-disable-next-line prefer-promise-reject-errors
|
|
326
|
-
: Promise.reject()
|
|
327
|
-
).
|
|
328
|
-
then(
|
|
329
|
-
() => fs.promises.
|
|
330
|
-
readFile(file, utf8).
|
|
331
|
-
then(jsoncParse).
|
|
332
|
-
then((/** @type {any} */ obj) => obj[packageName]),
|
|
333
|
-
noop
|
|
334
|
-
)
|
|
335
|
-
)
|
|
336
|
-
)
|
|
337
|
-
)
|
|
338
|
-
).
|
|
339
|
-
then((/** @type {Options} */ options) => {
|
|
349
|
+
|
|
350
|
+
// Load markdownlint-cli2 object(s)
|
|
351
|
+
processFirstMatchingConfigurationFile(context, optionsFiles, dir, (file) => { cli2File = file; }).
|
|
352
|
+
then((/** @type {Options | null} */ options) => {
|
|
340
353
|
dirInfo.markdownlintOptions = options;
|
|
341
354
|
return options &&
|
|
342
355
|
options.config &&
|
|
343
356
|
getExtendedConfig(
|
|
357
|
+
context,
|
|
344
358
|
options.config,
|
|
345
|
-
// Just need to identify
|
|
346
|
-
|
|
347
|
-
fs
|
|
359
|
+
// Just need to identify the right directory
|
|
360
|
+
pathPosix.join(dir, utf8)
|
|
348
361
|
).
|
|
349
362
|
then((config) => {
|
|
350
363
|
options.config = config;
|
|
351
364
|
});
|
|
352
365
|
}).
|
|
353
366
|
catch((/** @type {Error} */ error) => {
|
|
354
|
-
throwForConfigurationFile(
|
|
355
|
-
})
|
|
356
|
-
);
|
|
367
|
+
throwForConfigurationFile(cli2File, error);
|
|
368
|
+
}),
|
|
357
369
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
fs,
|
|
362
|
-
dir,
|
|
363
|
-
".markdownlint.jsonc",
|
|
364
|
-
readConfigFile(
|
|
365
|
-
fs,
|
|
366
|
-
dir,
|
|
367
|
-
".markdownlint.json",
|
|
368
|
-
readConfigFile(
|
|
369
|
-
fs,
|
|
370
|
-
dir,
|
|
371
|
-
".markdownlint.yaml",
|
|
372
|
-
readConfigFile(
|
|
373
|
-
fs,
|
|
374
|
-
dir,
|
|
375
|
-
".markdownlint.yml",
|
|
376
|
-
importConfig(
|
|
377
|
-
fs,
|
|
378
|
-
dir,
|
|
379
|
-
".markdownlint.cjs",
|
|
380
|
-
noImport,
|
|
381
|
-
importConfig(
|
|
382
|
-
fs,
|
|
383
|
-
dir,
|
|
384
|
-
".markdownlint.mjs",
|
|
385
|
-
noImport,
|
|
386
|
-
noop
|
|
387
|
-
)
|
|
388
|
-
)
|
|
389
|
-
)
|
|
390
|
-
)
|
|
391
|
-
)
|
|
392
|
-
);
|
|
393
|
-
tasks.push(
|
|
394
|
-
readConfigs().
|
|
395
|
-
then((/** @type {import("markdownlint").Configuration} */ config) => {
|
|
370
|
+
// Load markdownlint object(s)
|
|
371
|
+
processFirstMatchingConfigurationFile(context, configurationFiles, dir, noop).
|
|
372
|
+
then((/** @type {Configuration | null} */ config) => {
|
|
396
373
|
dirInfo.markdownlintConfig = config;
|
|
397
374
|
})
|
|
398
375
|
);
|
|
@@ -404,27 +381,24 @@ const getAndProcessDirInfo = (
|
|
|
404
381
|
|
|
405
382
|
// Get base markdownlint-cli2 options object
|
|
406
383
|
const getBaseOptions = async (
|
|
407
|
-
/** @type {
|
|
408
|
-
/** @type {string} */ baseDir,
|
|
384
|
+
/** @type {ExecutionContext} */ context,
|
|
409
385
|
/** @type {string | null} */ relativeDir,
|
|
410
386
|
/** @type {string[]} */ globPatterns,
|
|
411
387
|
/** @type {Options} */ options,
|
|
412
388
|
/** @type {boolean} */ fixDefault,
|
|
413
|
-
/** @type {boolean} */ noGlobs
|
|
414
|
-
/** @type {boolean} */ noImport
|
|
389
|
+
/** @type {boolean} */ noGlobs
|
|
415
390
|
) => {
|
|
391
|
+
const { baseDir } = context;
|
|
416
392
|
/** @type {Task[]} */
|
|
417
393
|
const tasks = [];
|
|
418
394
|
/** @type {DirToDirInfo} */
|
|
419
395
|
const dirToDirInfo = {};
|
|
420
396
|
getAndProcessDirInfo(
|
|
421
|
-
|
|
397
|
+
context,
|
|
422
398
|
tasks,
|
|
423
399
|
dirToDirInfo,
|
|
424
400
|
baseDir,
|
|
425
|
-
relativeDir
|
|
426
|
-
noImport,
|
|
427
|
-
true
|
|
401
|
+
relativeDir
|
|
428
402
|
);
|
|
429
403
|
await Promise.all(tasks);
|
|
430
404
|
// eslint-disable-next-line no-multi-assign
|
|
@@ -457,15 +431,13 @@ const getBaseOptions = async (
|
|
|
457
431
|
|
|
458
432
|
// Enumerate files from globs and build directory infos
|
|
459
433
|
const enumerateFiles = async (
|
|
460
|
-
/** @type {
|
|
461
|
-
/** @type {string} */ baseDirSystem,
|
|
462
|
-
/** @type {string} */ baseDir,
|
|
434
|
+
/** @type {ExecutionContext} */ context,
|
|
463
435
|
/** @type {string[]} */ globPatterns,
|
|
464
436
|
/** @type {DirToDirInfo} */ dirToDirInfo,
|
|
465
437
|
/** @type {boolean} */ gitignore,
|
|
466
|
-
/** @type {string | undefined} */ ignoreFiles
|
|
467
|
-
/** @type {boolean} */ noImport
|
|
438
|
+
/** @type {string | undefined} */ ignoreFiles
|
|
468
439
|
) => {
|
|
440
|
+
const { baseDir, baseDirSystem, fs } = context;
|
|
469
441
|
/** @type {Task[]} */
|
|
470
442
|
const tasks = [];
|
|
471
443
|
/** @type {import("globby").Options} */
|
|
@@ -473,7 +445,7 @@ const enumerateFiles = async (
|
|
|
473
445
|
"absolute": true,
|
|
474
446
|
"cwd": baseDir,
|
|
475
447
|
"dot": true,
|
|
476
|
-
"
|
|
448
|
+
"expandNegationOnlyPatterns": false,
|
|
477
449
|
gitignore,
|
|
478
450
|
ignoreFiles,
|
|
479
451
|
"suppressErrors": true,
|
|
@@ -501,41 +473,19 @@ const enumerateFiles = async (
|
|
|
501
473
|
((literalFiles.length > 0) && (globsForIgnore.length > 0))
|
|
502
474
|
? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore)
|
|
503
475
|
: literalFiles;
|
|
504
|
-
// Manually expand directories to avoid globby call to dir-glob.sync
|
|
505
|
-
const expandedDirectories = await Promise.all(
|
|
506
|
-
filteredGlobPatterns.map((globPattern) => {
|
|
507
|
-
const barePattern =
|
|
508
|
-
globPattern.startsWith("!")
|
|
509
|
-
? globPattern.slice(1)
|
|
510
|
-
: globPattern;
|
|
511
|
-
const globPath = (
|
|
512
|
-
pathPosix.isAbsolute(barePattern) ||
|
|
513
|
-
pathDefault.isAbsolute(barePattern)
|
|
514
|
-
)
|
|
515
|
-
? barePattern
|
|
516
|
-
: pathPosix.join(baseDir, barePattern);
|
|
517
|
-
return fs.promises.stat(globPath).
|
|
518
|
-
then((/** @type {import("node:fs").Stats} */ stats) => (stats.isDirectory()
|
|
519
|
-
? pathPosix.join(globPattern, "**")
|
|
520
|
-
: globPattern)).
|
|
521
|
-
catch(() => globPattern);
|
|
522
|
-
})
|
|
523
|
-
);
|
|
524
476
|
// Process glob patterns
|
|
525
477
|
const files = [
|
|
526
|
-
...await globby(
|
|
478
|
+
...await globby(filteredGlobPatterns, globbyOptions),
|
|
527
479
|
...filteredLiteralFiles
|
|
528
480
|
];
|
|
529
481
|
for (const file of files) {
|
|
530
482
|
const dir = pathPosix.dirname(file);
|
|
531
483
|
const dirInfo = getAndProcessDirInfo(
|
|
532
|
-
|
|
484
|
+
context,
|
|
533
485
|
tasks,
|
|
534
486
|
dirToDirInfo,
|
|
535
487
|
dir,
|
|
536
|
-
null
|
|
537
|
-
noImport,
|
|
538
|
-
false
|
|
488
|
+
null
|
|
539
489
|
);
|
|
540
490
|
dirInfo.files.push(file);
|
|
541
491
|
}
|
|
@@ -544,11 +494,10 @@ const enumerateFiles = async (
|
|
|
544
494
|
|
|
545
495
|
// Enumerate (possibly missing) parent directories and update directory infos
|
|
546
496
|
const enumerateParents = async (
|
|
547
|
-
/** @type {
|
|
548
|
-
/** @type {
|
|
549
|
-
/** @type {DirToDirInfo} */ dirToDirInfo,
|
|
550
|
-
/** @type {boolean} */ noImport
|
|
497
|
+
/** @type {ExecutionContext} */ context,
|
|
498
|
+
/** @type {DirToDirInfo} */ dirToDirInfo
|
|
551
499
|
) => {
|
|
500
|
+
const { baseDir } = context;
|
|
552
501
|
/** @type {Task[]} */
|
|
553
502
|
const tasks = [];
|
|
554
503
|
|
|
@@ -573,13 +522,11 @@ const enumerateParents = async (
|
|
|
573
522
|
lastDir = dir;
|
|
574
523
|
const dirInfo =
|
|
575
524
|
getAndProcessDirInfo(
|
|
576
|
-
|
|
525
|
+
context,
|
|
577
526
|
tasks,
|
|
578
527
|
dirToDirInfo,
|
|
579
528
|
dir,
|
|
580
|
-
null
|
|
581
|
-
noImport,
|
|
582
|
-
false
|
|
529
|
+
null
|
|
583
530
|
);
|
|
584
531
|
lastDirInfo.parent = dirInfo;
|
|
585
532
|
lastDirInfo = dirInfo;
|
|
@@ -595,31 +542,23 @@ const enumerateParents = async (
|
|
|
595
542
|
|
|
596
543
|
// Create directory info objects by enumerating file globs
|
|
597
544
|
const createDirInfos = async (
|
|
598
|
-
/** @type {
|
|
599
|
-
/** @type {string} */ baseDirSystem,
|
|
600
|
-
/** @type {string} */ baseDir,
|
|
545
|
+
/** @type {ExecutionContext} */ context,
|
|
601
546
|
/** @type {string[]} */ globPatterns,
|
|
602
547
|
/** @type {DirToDirInfo} */ dirToDirInfo,
|
|
603
548
|
/** @type {Options | undefined} */ optionsOverride,
|
|
604
549
|
/** @type {boolean} */ gitignore,
|
|
605
|
-
/** @type {string | undefined} */ ignoreFiles
|
|
606
|
-
/** @type {boolean} */ noImport
|
|
550
|
+
/** @type {string | undefined} */ ignoreFiles
|
|
607
551
|
) => {
|
|
608
552
|
await enumerateFiles(
|
|
609
|
-
|
|
610
|
-
baseDirSystem,
|
|
611
|
-
baseDir,
|
|
553
|
+
context,
|
|
612
554
|
globPatterns,
|
|
613
555
|
dirToDirInfo,
|
|
614
556
|
gitignore,
|
|
615
|
-
ignoreFiles
|
|
616
|
-
noImport
|
|
557
|
+
ignoreFiles
|
|
617
558
|
);
|
|
618
559
|
await enumerateParents(
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
dirToDirInfo,
|
|
622
|
-
noImport
|
|
560
|
+
context,
|
|
561
|
+
dirToDirInfo
|
|
623
562
|
);
|
|
624
563
|
|
|
625
564
|
// Merge file lists with identical configuration
|
|
@@ -635,6 +574,7 @@ const createDirInfos = async (
|
|
|
635
574
|
}
|
|
636
575
|
delete dirToDirInfo[dir];
|
|
637
576
|
} else {
|
|
577
|
+
const { noImport } = context;
|
|
638
578
|
const { markdownlintOptions, relativeDir } = dirInfo;
|
|
639
579
|
const effectiveDir = relativeDir || dir;
|
|
640
580
|
const effectiveModulePaths = resolveModulePaths(
|
|
@@ -704,8 +644,7 @@ const createDirInfos = async (
|
|
|
704
644
|
|
|
705
645
|
// Merge configuration by inheritance
|
|
706
646
|
for (const dirInfo of dirInfos) {
|
|
707
|
-
let markdownlintOptions = dirInfo
|
|
708
|
-
let { markdownlintConfig } = dirInfo;
|
|
647
|
+
let { markdownlintConfig, markdownlintOptions } = dirInfo;
|
|
709
648
|
/** @type {DirInfo | null} */
|
|
710
649
|
let parent = dirInfo;
|
|
711
650
|
// eslint-disable-next-line prefer-destructuring
|
|
@@ -719,7 +658,7 @@ const createDirInfos = async (
|
|
|
719
658
|
if (
|
|
720
659
|
!markdownlintConfig &&
|
|
721
660
|
parent.markdownlintConfig &&
|
|
722
|
-
!markdownlintOptions
|
|
661
|
+
!markdownlintOptions?.config
|
|
723
662
|
) {
|
|
724
663
|
// eslint-disable-next-line prefer-destructuring
|
|
725
664
|
markdownlintConfig = parent.markdownlintConfig;
|
|
@@ -735,7 +674,13 @@ const createDirInfos = async (
|
|
|
735
674
|
};
|
|
736
675
|
|
|
737
676
|
// Lint files in groups by shared configuration
|
|
738
|
-
const lintFiles = (
|
|
677
|
+
const lintFiles = (
|
|
678
|
+
/** @type {ExecutionContext} */ context,
|
|
679
|
+
/** @type {DirInfo[]} */ dirInfos,
|
|
680
|
+
/** @type {Record<string, string>} */ fileContents,
|
|
681
|
+
/** @type {FormattingContext} */ formattingContext
|
|
682
|
+
) => {
|
|
683
|
+
const { fs, parsers } = context;
|
|
739
684
|
const tasks = [];
|
|
740
685
|
// For each dirInfo
|
|
741
686
|
for (const dirInfo of dirInfos) {
|
|
@@ -743,6 +688,7 @@ const lintFiles = (/** @type {FsLike} */ fs, /** @type {DirInfo[]} */ dirInfos,
|
|
|
743
688
|
// Filter file/string inputs to only those in the dirInfo
|
|
744
689
|
let filesAfterIgnores = files;
|
|
745
690
|
if (
|
|
691
|
+
markdownlintOptions &&
|
|
746
692
|
markdownlintOptions.ignores &&
|
|
747
693
|
(markdownlintOptions.ignores.length > 0)
|
|
748
694
|
) {
|
|
@@ -766,7 +712,7 @@ const lintFiles = (/** @type {FsLike} */ fs, /** @type {DirInfo[]} */ dirInfos,
|
|
|
766
712
|
// eslint-disable-next-line no-inline-comments
|
|
767
713
|
const module = await import(/* webpackMode: "eager" */ "markdown-it");
|
|
768
714
|
const markdownIt = module.default({ "html": true });
|
|
769
|
-
for (const plugin of (markdownlintOptions
|
|
715
|
+
for (const plugin of (markdownlintOptions?.markdownItPlugins || [])) {
|
|
770
716
|
// @ts-ignore
|
|
771
717
|
markdownIt.use(...plugin);
|
|
772
718
|
}
|
|
@@ -777,16 +723,16 @@ const lintFiles = (/** @type {FsLike} */ fs, /** @type {DirInfo[]} */ dirInfos,
|
|
|
777
723
|
const options = {
|
|
778
724
|
"files": filteredFiles,
|
|
779
725
|
"strings": filteredStrings,
|
|
780
|
-
"config": markdownlintConfig || markdownlintOptions
|
|
726
|
+
"config": markdownlintConfig || markdownlintOptions?.config,
|
|
781
727
|
"configParsers": parsers,
|
|
782
728
|
// @ts-ignore
|
|
783
729
|
"customRules": markdownlintOptions.customRules,
|
|
784
|
-
"frontMatter": markdownlintOptions
|
|
785
|
-
? new RegExp(markdownlintOptions
|
|
730
|
+
"frontMatter": markdownlintOptions?.frontMatter
|
|
731
|
+
? new RegExp(markdownlintOptions?.frontMatter, "u")
|
|
786
732
|
: undefined,
|
|
787
733
|
"handleRuleFailures": true,
|
|
788
734
|
markdownItFactory,
|
|
789
|
-
"noInlineConfig": Boolean(markdownlintOptions
|
|
735
|
+
"noInlineConfig": Boolean(markdownlintOptions?.noInlineConfig),
|
|
790
736
|
fs
|
|
791
737
|
};
|
|
792
738
|
// Invoke markdownlint
|
|
@@ -799,7 +745,7 @@ const lintFiles = (/** @type {FsLike} */ fs, /** @type {DirInfo[]} */ dirInfos,
|
|
|
799
745
|
formattingContext.formatted = applyFixes(original, errorInfos);
|
|
800
746
|
return {};
|
|
801
747
|
});
|
|
802
|
-
} else if (markdownlintOptions
|
|
748
|
+
} else if (markdownlintOptions?.fix) {
|
|
803
749
|
// For any fixable errors, read file, apply fixes, write it back, and re-lint
|
|
804
750
|
task = task.then((results) => {
|
|
805
751
|
options.files = [];
|
|
@@ -836,7 +782,7 @@ const lintFiles = (/** @type {FsLike} */ fs, /** @type {DirInfo[]} */ dirInfos,
|
|
|
836
782
|
};
|
|
837
783
|
|
|
838
784
|
// Create list of results
|
|
839
|
-
const createResults = (/** @type {string} */ baseDir, /** @type {
|
|
785
|
+
const createResults = (/** @type {string} */ baseDir, /** @type {LintResults[]} */ taskResults) => {
|
|
840
786
|
/** @type {LintResult[]} */
|
|
841
787
|
const results = [];
|
|
842
788
|
/** @type {Map<LintResult, number>} */
|
|
@@ -907,7 +853,6 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
907
853
|
optionsDefault,
|
|
908
854
|
optionsOverride,
|
|
909
855
|
fileContents,
|
|
910
|
-
noImport,
|
|
911
856
|
allowStdin
|
|
912
857
|
} = params;
|
|
913
858
|
let {
|
|
@@ -917,6 +862,7 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
917
862
|
const logMessage = params.logMessage || noop;
|
|
918
863
|
const logError = params.logError || noop;
|
|
919
864
|
const fs = params.fs || fsNode;
|
|
865
|
+
const noImport = Boolean(params.noImport);
|
|
920
866
|
const baseDirSystem =
|
|
921
867
|
(directory && pathDefault.resolve(directory)) ||
|
|
922
868
|
process.cwd();
|
|
@@ -928,6 +874,9 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
928
874
|
/** @type {undefined | null | string} */
|
|
929
875
|
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
930
876
|
let configPath = undefined;
|
|
877
|
+
/** @type {undefined | null | string} */
|
|
878
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
879
|
+
let configPointer = undefined;
|
|
931
880
|
let useStdin = false;
|
|
932
881
|
let sawDashDash = false;
|
|
933
882
|
let shouldShowHelp = false;
|
|
@@ -936,6 +885,8 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
936
885
|
return true;
|
|
937
886
|
} else if (configPath === null) {
|
|
938
887
|
configPath = arg;
|
|
888
|
+
} else if (configPointer === null) {
|
|
889
|
+
configPointer = arg;
|
|
939
890
|
} else if ((arg === "-") && allowStdin) {
|
|
940
891
|
useStdin = true;
|
|
941
892
|
// eslint-disable-next-line unicorn/prefer-switch
|
|
@@ -943,6 +894,8 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
943
894
|
sawDashDash = true;
|
|
944
895
|
} else if (arg === "--config") {
|
|
945
896
|
configPath = null;
|
|
897
|
+
} else if (arg === "--configPointer") {
|
|
898
|
+
configPointer = null;
|
|
946
899
|
} else if (arg === "--fix") {
|
|
947
900
|
fixDefault = true;
|
|
948
901
|
} else if (arg === "--format") {
|
|
@@ -960,6 +913,8 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
960
913
|
if (shouldShowHelp) {
|
|
961
914
|
return showHelp(logMessage, true);
|
|
962
915
|
}
|
|
916
|
+
/** @type {ExecutionContext} */
|
|
917
|
+
const context = { baseDir, baseDirSystem, fs, noImport, "parsers": allParsers };
|
|
963
918
|
// Read argv configuration file (if relevant and present)
|
|
964
919
|
let optionsArgv = null;
|
|
965
920
|
let relativeDir = null;
|
|
@@ -967,23 +922,19 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
967
922
|
let baseOptions = null;
|
|
968
923
|
try {
|
|
969
924
|
if (configPath) {
|
|
970
|
-
const resolvedConfigPath =
|
|
971
|
-
|
|
972
|
-
optionsArgv =
|
|
973
|
-
await readOptionsOrConfig(resolvedConfigPath, fs, Boolean(noImport));
|
|
925
|
+
const resolvedConfigPath = posixPath(pathDefault.resolve(baseDirSystem, configPath));
|
|
926
|
+
optionsArgv = await readOptionsOrConfig(context, resolvedConfigPath, configPointer);
|
|
974
927
|
relativeDir = pathPosix.dirname(resolvedConfigPath);
|
|
975
928
|
}
|
|
976
929
|
// Process arguments and get base options
|
|
977
930
|
globPatterns = processArgv(argvFiltered);
|
|
978
931
|
baseOptions = await getBaseOptions(
|
|
979
|
-
|
|
980
|
-
baseDir,
|
|
932
|
+
context,
|
|
981
933
|
relativeDir,
|
|
982
934
|
globPatterns,
|
|
983
935
|
optionsArgv || optionsDefault,
|
|
984
936
|
fixDefault,
|
|
985
|
-
Boolean(noGlobs)
|
|
986
|
-
Boolean(noImport)
|
|
937
|
+
Boolean(noGlobs)
|
|
987
938
|
);
|
|
988
939
|
} finally {
|
|
989
940
|
if (!baseOptions?.baseMarkdownlintOptions.noBanner && !formattingContext.formatting) {
|
|
@@ -1026,24 +977,18 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
1026
977
|
logMessage(`Finding: ${globPatterns.join(" ")}`);
|
|
1027
978
|
}
|
|
1028
979
|
// Create linting tasks
|
|
1029
|
-
const gitignore =
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
(!params.fs && (typeof baseMarkdownlintOptions.gitignore === "string"))
|
|
1034
|
-
? baseMarkdownlintOptions.gitignore
|
|
1035
|
-
: undefined;
|
|
980
|
+
const gitignore = (baseMarkdownlintOptions.gitignore === true);
|
|
981
|
+
const ignoreFiles = (typeof baseMarkdownlintOptions.gitignore === "string")
|
|
982
|
+
? baseMarkdownlintOptions.gitignore
|
|
983
|
+
: undefined;
|
|
1036
984
|
const dirInfos =
|
|
1037
985
|
await createDirInfos(
|
|
1038
|
-
|
|
1039
|
-
baseDirSystem,
|
|
1040
|
-
baseDir,
|
|
986
|
+
context,
|
|
1041
987
|
globPatterns,
|
|
1042
988
|
dirToDirInfo,
|
|
1043
989
|
optionsOverride,
|
|
1044
990
|
gitignore,
|
|
1045
|
-
ignoreFiles
|
|
1046
|
-
Boolean(noImport)
|
|
991
|
+
ignoreFiles
|
|
1047
992
|
);
|
|
1048
993
|
// Output linting status
|
|
1049
994
|
if (showProgress) {
|
|
@@ -1060,7 +1005,7 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
1060
1005
|
logMessage(`Linting: ${fileCount} file(s)`);
|
|
1061
1006
|
}
|
|
1062
1007
|
// Lint files
|
|
1063
|
-
const lintResults = await lintFiles(
|
|
1008
|
+
const lintResults = await lintFiles(context, dirInfos, resolvedFileContents, formattingContext);
|
|
1064
1009
|
// Output summary
|
|
1065
1010
|
const results = createResults(baseDir, lintResults);
|
|
1066
1011
|
if (showProgress) {
|
|
@@ -1106,6 +1051,15 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
1106
1051
|
|
|
1107
1052
|
/** @typedef {Promise<any>} Task */
|
|
1108
1053
|
|
|
1054
|
+
/**
|
|
1055
|
+
* @typedef ExecutionContext
|
|
1056
|
+
* @property {string} baseDir Base directory (POSIX).
|
|
1057
|
+
* @property {string} baseDirSystem Base directory (non-POSIX).
|
|
1058
|
+
* @property {FsLike} fs File system object.
|
|
1059
|
+
* @property {boolean} noImport No import.
|
|
1060
|
+
* @property {ConfigurationParser[]} parsers Configuration file parsers.
|
|
1061
|
+
*/
|
|
1062
|
+
|
|
1109
1063
|
/**
|
|
1110
1064
|
* @typedef Parameters
|
|
1111
1065
|
* @property {boolean} [allowStdin] Allow stdin.
|
|
@@ -1122,14 +1076,29 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
1122
1076
|
* @property {Options} [optionsOverride] Options override.
|
|
1123
1077
|
*/
|
|
1124
1078
|
|
|
1079
|
+
/** @typedef {import("markdownlint").Configuration} Configuration */
|
|
1080
|
+
|
|
1081
|
+
/** @typedef {import("markdownlint").ConfigurationParser} ConfigurationParser */
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* @typedef ConfigurationHandlerParams
|
|
1085
|
+
* @property {string} dir Configuration file directory.
|
|
1086
|
+
* @property {string} file Configuration file.
|
|
1087
|
+
* @property {FsLike} fs File system object.
|
|
1088
|
+
* @property {ConfigurationParser[]} parsers Configuration file parsers.
|
|
1089
|
+
* @property {boolean} noImport No import.
|
|
1090
|
+
*/
|
|
1091
|
+
|
|
1092
|
+
/** @typedef {[ string, (params: ConfigurationHandlerParams) => Promise<any> ] } ConfigurationFileAndHandler */
|
|
1093
|
+
|
|
1125
1094
|
/**
|
|
1126
1095
|
* @typedef DirInfo
|
|
1127
1096
|
* @property {string} dir Directory.
|
|
1128
1097
|
* @property {string | null} relativeDir Relative directory.
|
|
1129
1098
|
* @property {DirInfo | null} parent Parent.
|
|
1130
1099
|
* @property {string[]} files Files.
|
|
1131
|
-
* @property {
|
|
1132
|
-
* @property {Options} markdownlintOptions Options.
|
|
1100
|
+
* @property {Configuration | null} markdownlintConfig Configuration.
|
|
1101
|
+
* @property {Options | null} markdownlintOptions Options.
|
|
1133
1102
|
*/
|
|
1134
1103
|
|
|
1135
1104
|
/** @typedef {Record<string, DirInfo>} DirToDirInfo */
|
|
@@ -1138,10 +1107,12 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
1138
1107
|
|
|
1139
1108
|
/** @typedef {[string]} OutputFormatterConfiguration */
|
|
1140
1109
|
|
|
1110
|
+
/** @typedef {import("markdownlint").Rule} Rule */
|
|
1111
|
+
|
|
1141
1112
|
/**
|
|
1142
1113
|
* @typedef Options
|
|
1143
|
-
* @property {
|
|
1144
|
-
* @property {
|
|
1114
|
+
* @property {Configuration} [config] Config.
|
|
1115
|
+
* @property {Rule[] | string[]} [customRules] Custom rules.
|
|
1145
1116
|
* @property {boolean} [fix] Fix.
|
|
1146
1117
|
* @property {string} [frontMatter] Front matter.
|
|
1147
1118
|
* @property {boolean | string} [gitignore] Git ignore.
|
|
@@ -1163,6 +1134,8 @@ export const main = async (/** @type {Parameters} */ params) => {
|
|
|
1163
1134
|
|
|
1164
1135
|
/** @typedef {import("markdownlint").LintError & LintContext} LintResult */
|
|
1165
1136
|
|
|
1137
|
+
/** @typedef {import("markdownlint").LintResults} LintResults */
|
|
1138
|
+
|
|
1166
1139
|
/**
|
|
1167
1140
|
* @typedef FormattingContext
|
|
1168
1141
|
* @property {boolean} [formatting] True iff formatting.
|