mdrefine 0.2.0-rc.2 → 0.2.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +577 -0
  2. package/CODE_OF_CONDUCT.md +30 -0
  3. package/CONTRIBUTING.md +189 -16
  4. package/README.md +100 -154
  5. package/SECURITY.md +15 -13
  6. package/config.schema.json +91 -0
  7. package/dist/cli/diff.d.ts +10 -0
  8. package/dist/cli/diff.js +247 -0
  9. package/dist/cli/diff.js.map +1 -0
  10. package/dist/cli/main.js +270 -150
  11. package/dist/cli/main.js.map +1 -1
  12. package/dist/config/load.js +67 -6
  13. package/dist/config/load.js.map +1 -1
  14. package/dist/config/problems.d.ts +7 -0
  15. package/dist/config/problems.js +208 -0
  16. package/dist/config/problems.js.map +1 -0
  17. package/dist/config/resolve.d.ts +42 -109
  18. package/dist/config/resolve.js +193 -52
  19. package/dist/config/resolve.js.map +1 -1
  20. package/dist/core/directives.d.ts +7 -0
  21. package/dist/core/directives.js +25 -13
  22. package/dist/core/directives.js.map +1 -1
  23. package/dist/core/engine.d.ts +42 -4
  24. package/dist/core/engine.js +518 -79
  25. package/dist/core/engine.js.map +1 -1
  26. package/dist/core/frozen.d.ts +6 -0
  27. package/dist/core/frozen.js +15 -0
  28. package/dist/core/frozen.js.map +1 -0
  29. package/dist/core/scope.d.ts +30 -0
  30. package/dist/core/scope.js +122 -0
  31. package/dist/core/scope.js.map +1 -0
  32. package/dist/core/types.d.ts +202 -23
  33. package/dist/core/types.js.map +1 -1
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js.map +1 -1
  36. package/dist/node.d.ts +3 -0
  37. package/dist/node.js +4 -0
  38. package/dist/node.js.map +1 -0
  39. package/dist/rules/blocks.d.ts +34 -0
  40. package/dist/rules/blocks.js +550 -0
  41. package/dist/rules/blocks.js.map +1 -0
  42. package/dist/rules/content.d.ts +2 -0
  43. package/dist/rules/content.js +85 -0
  44. package/dist/rules/content.js.map +1 -0
  45. package/dist/rules/dialects.js +10 -6
  46. package/dist/rules/dialects.js.map +1 -1
  47. package/dist/rules/links.js +302 -6
  48. package/dist/rules/links.js.map +1 -1
  49. package/dist/rules/lists.d.ts +2 -0
  50. package/dist/rules/lists.js +924 -0
  51. package/dist/rules/lists.js.map +1 -0
  52. package/dist/rules/structure.js +127 -1
  53. package/dist/rules/structure.js.map +1 -1
  54. package/dist/rules/style.d.ts +8 -2
  55. package/dist/rules/style.js +1137 -165
  56. package/dist/rules/style.js.map +1 -1
  57. package/dist/syntax/block-identifier.d.ts +18 -0
  58. package/dist/syntax/block-identifier.js +24 -0
  59. package/dist/syntax/block-identifier.js.map +1 -0
  60. package/dist/syntax/obsidian.d.ts +29 -11
  61. package/dist/syntax/obsidian.js +9 -10
  62. package/dist/syntax/obsidian.js.map +1 -1
  63. package/dist/syntax/parse.d.ts +87 -3
  64. package/dist/syntax/parse.js +247 -19
  65. package/dist/syntax/parse.js.map +1 -1
  66. package/dist/workspace/access.d.ts +12 -3
  67. package/dist/workspace/access.js +33 -5
  68. package/dist/workspace/access.js.map +1 -1
  69. package/dist/workspace/discovery.d.ts +85 -0
  70. package/dist/workspace/discovery.js +155 -0
  71. package/dist/workspace/discovery.js.map +1 -0
  72. package/dist/workspace/encoding.d.ts +24 -0
  73. package/dist/workspace/encoding.js +113 -0
  74. package/dist/workspace/encoding.js.map +1 -0
  75. package/dist/workspace/files.d.ts +92 -6
  76. package/dist/workspace/files.js +715 -59
  77. package/dist/workspace/files.js.map +1 -1
  78. package/dist/workspace/git.d.ts +54 -0
  79. package/dist/workspace/git.js +198 -0
  80. package/dist/workspace/git.js.map +1 -0
  81. package/dist/workspace/index.d.ts +58 -3
  82. package/dist/workspace/index.js +136 -37
  83. package/dist/workspace/index.js.map +1 -1
  84. package/dist/workspace/selection.d.ts +2 -2
  85. package/dist/workspace/selection.js +3 -3
  86. package/dist/workspace/selection.js.map +1 -1
  87. package/dist/workspace/slug.js +8 -1
  88. package/dist/workspace/slug.js.map +1 -1
  89. package/dist/workspace/vault.js +3 -1
  90. package/dist/workspace/vault.js.map +1 -1
  91. package/docs/api.md +239 -0
  92. package/docs/benchmarks.md +140 -200
  93. package/docs/changelog.md +1 -0
  94. package/docs/cli.md +281 -89
  95. package/docs/configuration.md +193 -480
  96. package/docs/design.md +163 -284
  97. package/docs/dialects.md +169 -0
  98. package/docs/examples.md +151 -109
  99. package/docs/index.md +21 -37
  100. package/docs/integrations.md +144 -0
  101. package/docs/obsidian.md +91 -115
  102. package/docs/plugins.md +147 -212
  103. package/docs/quick-start.md +68 -74
  104. package/docs/rules.md +1237 -0
  105. package/docs/versions.md +56 -0
  106. package/examples/README.md +17 -14
  107. package/examples/automation/summarize-report.mjs +5 -2
  108. package/examples/library/lint-folder.mjs +5 -4
  109. package/examples/library/lint-workspace.mjs +32 -0
  110. package/examples/plugin/notes/release-checklist.md +2 -2
  111. package/examples/plugin/rules.mjs +17 -23
  112. package/examples/workspaces/obsidian-vault/after/mdtools.config.jsonc +2 -2
  113. package/examples/workspaces/obsidian-vault/before/mdtools.config.jsonc +2 -2
  114. package/examples/workspaces/repository-docs/after/README.md +2 -2
  115. package/examples/workspaces/repository-docs/after/mdtools.config.jsonc +0 -2
  116. package/examples/workspaces/repository-docs/before/README.md +2 -2
  117. package/examples/workspaces/repository-docs/before/docs/guide.md +7 -7
  118. package/examples/workspaces/repository-docs/before/docs/reference.md +3 -1
  119. package/examples/workspaces/repository-docs/before/mdtools.config.jsonc +0 -2
  120. package/package.json +38 -12
  121. package/docs/contributing.md +0 -218
  122. package/docs/releases/0.1.0-beta.1.md +0 -39
  123. package/docs/releases/0.1.0-beta.2.md +0 -83
  124. package/docs/releases/0.1.0-beta.3.md +0 -61
  125. package/docs/releases/0.1.0-beta.4.md +0 -50
  126. package/docs/releases/0.1.0-rc.1.md +0 -99
  127. package/docs/releases/0.2.0-rc.1.md +0 -141
  128. package/docs/releases/0.2.0-rc.2.md +0 -225
  129. package/docs/releases.md +0 -144
  130. package/docs/testing.md +0 -93
@@ -0,0 +1 @@
1
+ {"version":3,"file":"problems.js","sourceRoot":"","sources":["../../src/config/problems.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ErrorObject } from \"ajv\";\n\n/** A short description of a value that was given where something else belongs. */\nexport function shown(value: unknown): string {\n switch (typeof value) {\n case \"string\":\n return JSON.stringify(value.length > 40 ? `${value.slice(0, 40)}…` : value);\n case \"number\":\n case \"bigint\":\n case \"boolean\":\n case \"undefined\":\n return String(value);\n case \"function\":\n return \"a function\";\n case \"symbol\":\n return \"a symbol\";\n default:\n return value === null ? \"null\" : Array.isArray(value) ? \"a list\" : \"an object\";\n }\n}\n/** Alternatives in prose: `\"a\", \"b\", or \"c\"`. */\nfunction either(items: readonly string[]): string {\n return items.length < 3\n ? items.join(\" or \")\n : `${items.slice(0, -1).join(\", \")}, or ${items.at(-1)}`;\n}\n/** The keys of a JSON pointer, such as `/rules/style~1wrap`, unescaped. */\nfunction keys(pointer: string): string[] {\n return pointer\n ? pointer\n .slice(1)\n .split(\"/\")\n .map((key) => key.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"))\n : [];\n}\n/** Keys as a path written the way a reader finds them in a file: `overrides[0].files`. */\nfunction written(path: readonly string[]): string {\n let text = \"\";\n for (const key of path) text += /^\\d+$/.test(key) ? `[${key}]` : text ? `.${key}` : key;\n return text;\n}\n/** The part of `value` at `path`. */\nfunction at(value: unknown, path: readonly string[]): unknown {\n for (const key of path)\n value =\n value && typeof value === \"object\" && Object.hasOwn(value, key)\n ? (value as Record<string, unknown>)[key]\n : undefined;\n return value;\n}\nconst typeWords: Record<string, string> = {\n string: \"a string\",\n number: \"a number\",\n integer: \"an integer\",\n boolean: \"true or false\",\n object: \"an object\",\n array: \"a list\",\n null: \"null\",\n};\n/** Limits in plain words, by keyword. */\nconst limits: Record<string, (limit: unknown) => string> = {\n minimum: (limit) => `must be at least ${String(limit)}`,\n maximum: (limit) => `must be at most ${String(limit)}`,\n exclusiveMinimum: (limit) => `must be more than ${String(limit)}`,\n exclusiveMaximum: (limit) => `must be less than ${String(limit)}`,\n minItems: (limit) => `must hold at least ${String(limit)} item(s)`,\n maxItems: (limit) => `must hold at most ${String(limit)} item(s)`,\n minLength: (limit) => `must be at least ${String(limit)} character(s) long`,\n maxLength: (limit) => `must be at most ${String(limit)} character(s) long`,\n};\n/** Keywords whose failure means that the value itself is of the wrong kind, so naming it helps. */\nconst kinds = new Set([\"type\", \"enum\", \"const\"]);\n\n/** What a part of the configuration is called in a message, and what it must be. */\ninterface Place {\n /** Places of one setting, whose errors are reported together. */\n setting: string;\n label: string;\n expected?: string;\n}\nconst severities = either(['\"off\"', '\"warn\"', '\"error\"']);\n/** Where `path` lies in a configuration, or in the override `scope` when it is set. */\nfunction place(path: readonly string[], dialects: readonly string[], scope?: string): Place {\n const [key, ...rest] = path;\n const name = (keys: readonly string[]) => `\"${scope ? `${scope}.` : \"\"}${written(keys)}\"`;\n const setting = written(scope ? [scope, ...path.slice(0, 1)] : path.slice(0, 1));\n const item = (whole: string, one: string): Place =>\n rest.length\n ? { setting, label: name(path.slice(0, 2)), expected: one }\n : { setting, label: name(path), expected: whole };\n switch (key) {\n case undefined:\n return scope\n ? { setting: scope, label: `\"${scope}\"`, expected: 'an object with \"files\"' }\n : { setting: \"\", label: \"the configuration\", expected: \"an object\" };\n case \"$schema\":\n return { setting, label: name(path), expected: \"a string\" };\n case \"resolve\":\n return rest.length\n ? {\n setting: written(path.slice(0, 2)),\n label: name(path.slice(0, 2)),\n expected: \"true or false\",\n }\n : { setting, label: name(path), expected: \"an object\" };\n case \"extends\":\n return item(\"a preset name or a list of preset names\", \"a preset name\");\n case \"dialect\":\n return { setting, label: name(path), expected: either(dialects.map((item) => `\"${item}\"`)) };\n case \"ignore\":\n return item(\"a list of path patterns\", \"a path pattern\");\n case \"plugins\":\n return item(\"a list of file or package names\", \"a file or package name\");\n case \"files\":\n return item(\"a list of one or more path patterns\", \"a path pattern\");\n case \"rules\": {\n const [id, part] = rest;\n if (id === undefined)\n return { setting, label: name(path), expected: \"an object of rule IDs and their settings\" };\n const of = `\"${id}\"${scope ? ` in \"${scope}\"` : \"\"}`;\n const rule = `${setting}/${id}`;\n if (part === \"0\")\n return { setting: rule, label: `the severity of ${of}`, expected: severities };\n if (part === \"1\")\n return { setting: rule, label: `the options of ${of}`, expected: \"an object\" };\n return {\n setting: rule,\n label: `the setting of ${of}`,\n expected: `${severities}, or a list of a severity and, optionally, the rule's options`,\n };\n }\n case \"overrides\": {\n const [index, ...inside] = rest;\n if (index === undefined)\n return { setting, label: name(path), expected: 'a list of objects with \"files\"' };\n return place(inside, dialects, `overrides[${index}]`);\n }\n default:\n return { setting: written(path), label: name(path) };\n }\n}\n\n/**\n * Validation errors of a JSON Schema as one message in plain words, with each\n * part named as it is written in the file: `\"extends[1]\" must be a preset name,\n * not 5`. `describe` names a part and says what it must be; without\n * `expected`, the validator's own words say it. Of the errors of one setting,\n * only those deepest in the value are kept: they are the ones that a list or\n * an object allowed as a whole still breaks.\n */\nfunction phrased(\n errors: readonly ErrorObject[],\n value: unknown,\n describe: (path: readonly string[]) => Place,\n unknown: string,\n): string {\n const messages = new Set<string>();\n /** The remaining errors of each setting, at the depth that counts. */\n const settings = new Map<string, { depth: number; errors: ErrorObject[] }>();\n for (const error of errors) {\n const path = keys(error.instancePath);\n if (error.keyword === \"additionalProperties\") {\n const extra = String((error.params as { additionalProperty: string }).additionalProperty);\n messages.add(`unknown ${unknown} \"${written([...path, extra])}\"`);\n continue;\n }\n if (error.keyword === \"required\") {\n const missing = String((error.params as { missingProperty: string }).missingProperty);\n messages.add(`${describe(path).label} must have \"${missing}\"`);\n continue;\n }\n // A summary of alternatives that each failed; the alternatives say how.\n if (error.keyword === \"anyOf\" || error.keyword === \"oneOf\") continue;\n const { setting } = describe(path);\n const held = settings.get(setting);\n if (!held || path.length > held.depth)\n settings.set(setting, { depth: path.length, errors: [error] });\n else if (path.length === held.depth) held.errors.push(error);\n }\n for (const { errors: kept } of settings.values()) {\n const byPath = new Map<string, ErrorObject[]>();\n for (const error of kept)\n byPath.set(error.instancePath, [...(byPath.get(error.instancePath) ?? []), error]);\n for (const [pointer, group] of byPath) {\n const path = keys(pointer);\n const { label, expected } = describe(path);\n const given = group.every((error) => kinds.has(error.keyword))\n ? `, not ${shown(at(value, path))}`\n : \"\";\n if (expected) messages.add(`${label} must be ${expected}${given}`);\n else {\n const types = group.flatMap((error) =>\n error.keyword === \"type\" ? [error.params as { type: string | string[] }] : [],\n );\n if (types.length === group.length)\n messages.add(\n `${label} must be ${either(types.flatMap(({ type }) => type).map((type) => typeWords[type] ?? type))}${given}`,\n );\n else\n for (const error of group) {\n const { allowedValues, limit } = error.params as {\n allowedValues?: unknown[];\n limit?: unknown;\n };\n const limited = limits[error.keyword];\n messages.add(\n error.keyword === \"enum\" && allowedValues\n ? `${label} must be ${either(allowedValues.map((item) => JSON.stringify(item)))}${given}`\n : limited && limit !== undefined\n ? `${label} ${limited(limit)}`\n : `${label} ${error.message ?? \"is not valid\"}${kinds.has(error.keyword) ? given : \"\"}`,\n );\n }\n }\n }\n }\n return [...messages].join(\"; \");\n}\n\n/** The configuration's validation errors in plain words, naming each setting as it is written. */\nexport function configErrors(\n errors: readonly ErrorObject[],\n value: unknown,\n dialects: readonly string[],\n): string {\n return phrased(errors, value, (path) => place(path, dialects), \"setting\");\n}\n/** A rule's option errors in plain words, naming each option as it is written. */\nexport function optionErrors(errors: readonly ErrorObject[], value: unknown): string {\n return phrased(\n errors,\n value,\n (path) => ({\n setting: written(path),\n label: path.length ? `\"${written(path)}\"` : \"the options\",\n }),\n \"option\",\n );\n}\n"]}
@@ -1,7 +1,11 @@
1
- import type { Config, Dialect, DialectName, Plugin, ResolvedConfig, RuleSetting } from "../core/types.js";
2
- /** Alias names that select an existing dialect; Codeberg runs Forgejo's renderer. */
3
- export declare const dialectAliases: Record<string, Dialect>;
4
- export declare const dialects: Dialect[];
1
+ import type { Config, Dialect, DialectName, JsonSchemaObject, ResolveConfigOptions, ResolvedConfig, RuleSetting } from "../core/types.js";
2
+ /**
3
+ * Alias names that select an existing dialect, mapped to that dialect:
4
+ * Codeberg runs Forgejo's renderer. The table is frozen.
5
+ */
6
+ export declare const dialectAliases: Readonly<Record<Exclude<DialectName, Dialect>, Dialect>>;
7
+ /** The dialects, in the order the documentation lists them. The list is frozen. */
8
+ export declare const dialects: readonly Dialect[];
5
9
  /**
6
10
  * The dialect assumed when nothing names one and the caller knows no better.
7
11
  * GitHub's syntax is the common base of the Forgejo, Gitea, and Obsidian
@@ -9,116 +13,45 @@ export declare const dialects: Dialect[];
9
13
  * ordinary paragraph and reflowed.
10
14
  */
11
15
  export declare const fallbackDialect: Dialect;
16
+ /**
17
+ * The dialect that `name` stands for: an alias's dialect, or `name` itself.
18
+ * A name that is neither is returned as it is.
19
+ */
12
20
  export declare function canonicalDialect(name: DialectName): Dialect;
13
- export declare const presets: Record<string, Config>;
14
- export declare const configSchema: {
15
- $schema: string;
16
- type: string;
17
- additionalProperties: boolean;
18
- properties: {
19
- $schema: {
20
- type: string;
21
- };
22
- resolve: {
23
- type: string;
24
- additionalProperties: boolean;
25
- properties: {
26
- gitIgnored: {
27
- type: string;
28
- };
29
- nestedRepositories: {
30
- type: string;
31
- };
32
- };
33
- };
34
- extends: {
35
- type: string;
36
- items: {
37
- type: string;
38
- };
39
- };
40
- dialect: {
41
- enum: string[];
42
- };
43
- rules: {
44
- type: string;
45
- additionalProperties: {
46
- anyOf: ({
47
- enum: string[];
48
- } | {
49
- type: string;
50
- items: ({
51
- enum: string[];
52
- } | {
53
- type: string;
54
- })[];
55
- minItems: number;
56
- maxItems: number;
57
- })[];
58
- };
59
- };
60
- ignore: {
61
- type: string;
62
- items: {
63
- type: string;
64
- };
65
- };
66
- plugins: {
67
- type: string;
68
- items: {
69
- type: string;
70
- };
71
- };
72
- overrides: {
73
- type: string;
74
- items: {
75
- type: string;
76
- required: string[];
77
- additionalProperties: boolean;
78
- properties: {
79
- files: {
80
- type: string;
81
- items: {
82
- type: string;
83
- };
84
- minItems: number;
85
- };
86
- dialect: {
87
- enum: string[];
88
- };
89
- rules: {
90
- type: string;
91
- additionalProperties: {
92
- anyOf: ({
93
- enum: string[];
94
- } | {
95
- type: string;
96
- items: ({
97
- enum: string[];
98
- } | {
99
- type: string;
100
- })[];
101
- minItems: number;
102
- maxItems: number;
103
- })[];
104
- };
105
- };
106
- };
107
- };
108
- };
109
- };
110
- };
111
- /** What is wrong with `value` as a configuration, or undefined when it is valid. */
21
+ /** The dialect that `name` stands for, or an error that says what was named. */
22
+ export declare function knownDialect(name: DialectName, what?: string): Dialect;
23
+ /**
24
+ * The built-in presets by name. The table and everything in it are frozen, so
25
+ * that no caller can change what another one gets.
26
+ */
27
+ export declare const presets: Readonly<Record<string, Readonly<Config>>>;
28
+ /**
29
+ * The configuration's JSON Schema, which `validateConfig` enforces. The
30
+ * package ships it as `config.schema.json`, which a test keeps equal to it,
31
+ * and the documentation site serves it for editors.
32
+ */
33
+ export declare const configSchema: JsonSchemaObject;
34
+ /** What is wrong with `value` as a configuration, in plain words, or undefined when it is valid. */
112
35
  export declare function configProblem(value: unknown): string | undefined;
36
+ /**
37
+ * Throws an error that says what is wrong when `value` is not a configuration
38
+ * that `configSchema` describes, naming each setting as it is written, as in
39
+ * `Invalid configuration: "extends[1]" must be a preset name, not 5`. Rule IDs,
40
+ * preset names, and rule options are checked when a document is processed.
41
+ */
113
42
  export declare function validateConfig(value: unknown): asserts value is Config;
114
43
  export declare function setting(value: RuleSetting): {
115
44
  severity: "off" | "warn" | "error";
116
- options: Record<string, unknown>;
45
+ options: Readonly<Record<string, unknown>>;
117
46
  };
118
47
  /**
119
- * The configuration in effect for the document at `path`. `defaultDialect` is
120
- * the dialect to assume when neither the configuration, a preset, nor a
121
- * matching override names one: `github` unless the caller knows better, as the
122
- * CLI does at the root of an Obsidian vault.
48
+ * The configuration in effect for one document: its dialect, rule settings,
49
+ * `ignore` patterns, and `resolve` settings. It takes the `path`, `config`,
50
+ * `plugins`, and `defaultDialect` that `lint` and `format` take, so their
51
+ * options serve as they are. `defaultDialect` is the dialect to assume when
52
+ * neither the configuration, a preset, nor a matching override names one:
53
+ * `github` unless the caller knows better, as the CLI does inside an Obsidian
54
+ * vault. An invalid configuration or default dialect, an unknown preset, and a
55
+ * cycle of presets throw an error.
123
56
  */
124
- export declare function resolveConfig(config?: Config, path?: string, plugins?: Plugin[], defaultDialect?: DialectName): ResolvedConfig;
57
+ export declare function resolveConfig(options?: ResolveConfigOptions): ResolvedConfig;
@@ -1,8 +1,20 @@
1
1
  import { Ajv } from "ajv";
2
- import { minimatch } from "minimatch";
3
- /** Alias names that select an existing dialect; Codeberg runs Forgejo's renderer. */
4
- export const dialectAliases = { codeberg: "forgejo" };
5
- export const dialects = ["commonmark", "github", "forgejo", "gitea", "obsidian"];
2
+ import { Minimatch } from "minimatch";
3
+ import { configErrors } from "./problems.js";
4
+ import { deepFreeze } from "../core/frozen.js";
5
+ /**
6
+ * Alias names that select an existing dialect, mapped to that dialect:
7
+ * Codeberg runs Forgejo's renderer. The table is frozen.
8
+ */
9
+ export const dialectAliases = Object.freeze({ codeberg: "forgejo" });
10
+ /** The dialects, in the order the documentation lists them. The list is frozen. */
11
+ export const dialects = Object.freeze([
12
+ "commonmark",
13
+ "github",
14
+ "forgejo",
15
+ "gitea",
16
+ "obsidian",
17
+ ]);
6
18
  /**
7
19
  * The dialect assumed when nothing names one and the caller knows no better.
8
20
  * GitHub's syntax is the common base of the Forgejo, Gitea, and Obsidian
@@ -10,17 +22,49 @@ export const dialects = ["commonmark", "github", "forgejo", "gitea", "obsidian"]
10
22
  * ordinary paragraph and reflowed.
11
23
  */
12
24
  export const fallbackDialect = "github";
25
+ /**
26
+ * The dialect that `name` stands for: an alias's dialect, or `name` itself.
27
+ * A name that is neither is returned as it is.
28
+ */
13
29
  export function canonicalDialect(name) {
14
- return dialectAliases[name] ?? name;
30
+ return Object.hasOwn(dialectAliases, name)
31
+ ? dialectAliases[name]
32
+ : name;
33
+ }
34
+ /** The dialect that `name` stands for, or an error that says what was named. */
35
+ export function knownDialect(name, what = "dialect") {
36
+ const dialect = canonicalDialect(name);
37
+ if (!dialects.includes(dialect))
38
+ throw new Error(`Unknown ${what}: ${String(name)}`);
39
+ return dialect;
15
40
  }
41
+ /**
42
+ * The built-in presets by name. The table and everything in it are frozen, so
43
+ * that no caller can change what another one gets.
44
+ */
16
45
  export const presets = {
17
46
  recommended: {
18
47
  rules: {
19
48
  "style/wrap": ["warn", { width: 80 }],
20
49
  "style/emphasis": ["warn", { marker: "_" }],
21
50
  "style/strong": ["warn", { marker: "*" }],
51
+ "style/heading": "warn",
52
+ "style/table": "warn",
53
+ "style/code-fence": "warn",
54
+ "style/thematic-break": "warn",
55
+ "style/blank-lines": "warn",
56
+ "style/trailing-space": "warn",
22
57
  "style/final-newline": "warn",
58
+ "style/list-marker": ["warn", { marker: "-" }],
59
+ "style/ordered-list": ["warn", { delimiter: ".", numbering: "auto" }],
60
+ "style/list-indent": "warn",
23
61
  "links/valid": "error",
62
+ "links/undefined-reference": "warn",
63
+ "links/unused-definition": "warn",
64
+ "links/empty": "warn",
65
+ "structure/heading-increment": "warn",
66
+ "content/image-alt": "warn",
67
+ "content/table-columns": "warn",
24
68
  },
25
69
  },
26
70
  github: {
@@ -57,97 +101,193 @@ export const presets = {
57
101
  },
58
102
  },
59
103
  };
60
- const severity = { enum: ["off", "warn", "error"] };
61
- const dialect = { enum: [...dialects, ...Object.keys(dialectAliases)] };
62
- const rules = {
63
- type: "object",
64
- additionalProperties: {
65
- anyOf: [
66
- severity,
67
- { type: "array", items: [severity, { type: "object" }], minItems: 2, maxItems: 2 },
68
- ],
69
- },
70
- };
71
- export const configSchema = {
104
+ deepFreeze(presets);
105
+ // Each dialect is followed by its aliases, as the command line lists them.
106
+ const dialectNames = dialects.flatMap((dialect) => [
107
+ dialect,
108
+ ...Object.entries(dialectAliases).flatMap(([alias, of]) => (of === dialect ? [alias] : [])),
109
+ ]);
110
+ const strings = { type: "array", items: { type: "string" } };
111
+ /**
112
+ * The configuration's JSON Schema, which `validateConfig` enforces. The
113
+ * package ships it as `config.schema.json`, which a test keeps equal to it,
114
+ * and the documentation site serves it for editors.
115
+ */
116
+ export const configSchema = deepFreeze({
72
117
  $schema: "http://json-schema.org/draft-07/schema#",
118
+ title: "mdtools configuration",
119
+ description: "Configuration of the mdtools command of mdrefine: https://viell-dev.github.io/slop-markdown-tools/configuration.html",
73
120
  type: "object",
74
121
  additionalProperties: false,
75
122
  properties: {
76
- $schema: { type: "string" },
123
+ $schema: { description: "The JSON Schema for editors; the tool ignores it.", type: "string" },
77
124
  resolve: {
125
+ description: "Files that links may lead to, which are never linted or formatted.",
78
126
  type: "object",
79
127
  additionalProperties: false,
80
- properties: { gitIgnored: { type: "boolean" }, nestedRepositories: { type: "boolean" } },
128
+ properties: {
129
+ gitIgnored: {
130
+ description: "Files that .gitignore files exclude are link targets. Default: false.",
131
+ type: "boolean",
132
+ },
133
+ nestedRepositories: {
134
+ description: "Files of nested Git repositories are link targets. Default: false.",
135
+ type: "boolean",
136
+ },
137
+ },
138
+ },
139
+ extends: {
140
+ description: "Presets to start from, in order: a preset name or a list of them. Without it, the configuration starts from recommended.",
141
+ anyOf: [{ type: "string" }, strings],
142
+ },
143
+ dialect: { $ref: "#/definitions/dialect" },
144
+ rules: { $ref: "#/definitions/rules" },
145
+ ignore: {
146
+ description: "Path patterns of documents that are never linted or formatted, matched with their letter case. They stay link targets.",
147
+ ...strings,
148
+ },
149
+ plugins: {
150
+ description: "Plugins to load: files relative to this file, or package names.",
151
+ ...strings,
81
152
  },
82
- extends: { type: "array", items: { type: "string" } },
83
- dialect,
84
- rules,
85
- ignore: { type: "array", items: { type: "string" } },
86
- plugins: { type: "array", items: { type: "string" } },
87
153
  overrides: {
154
+ description: "Settings for the documents that match one of the patterns in files.",
88
155
  type: "array",
89
156
  items: {
90
157
  type: "object",
91
158
  required: ["files"],
92
159
  additionalProperties: false,
93
160
  properties: {
94
- files: { type: "array", items: { type: "string" }, minItems: 1 },
95
- dialect,
96
- rules,
161
+ files: {
162
+ description: "Path patterns, matched with their letter case against paths relative to the workspace root.",
163
+ ...strings,
164
+ minItems: 1,
165
+ },
166
+ dialect: { $ref: "#/definitions/dialect" },
167
+ rules: { $ref: "#/definitions/rules" },
97
168
  },
98
169
  },
99
170
  },
100
171
  },
101
- };
172
+ definitions: {
173
+ dialect: {
174
+ description: "The renderer whose syntax documents are read in. When nothing names one, github is assumed, or obsidian inside a vault.",
175
+ enum: dialectNames,
176
+ },
177
+ severity: { enum: ["off", "warn", "error"] },
178
+ rules: {
179
+ description: 'Rule IDs and their settings: a severity, or a list of a severity and the rule\'s options, as in ["warn", { "width": 100 }].',
180
+ type: "object",
181
+ additionalProperties: {
182
+ anyOf: [
183
+ { $ref: "#/definitions/severity" },
184
+ { type: "array", items: [{ $ref: "#/definitions/severity" }], minItems: 1, maxItems: 1 },
185
+ {
186
+ type: "array",
187
+ items: [{ $ref: "#/definitions/severity" }, { type: "object" }],
188
+ minItems: 2,
189
+ maxItems: 2,
190
+ },
191
+ ],
192
+ },
193
+ },
194
+ },
195
+ });
102
196
  const validate = new Ajv({ allErrors: true }).compile(configSchema);
103
- /** What is wrong with `value` as a configuration, or undefined when it is valid. */
197
+ /** What is wrong with `value` as a configuration, in plain words, or undefined when it is valid. */
104
198
  export function configProblem(value) {
105
- return validate(value) ? undefined : new Ajv().errorsText(validate.errors);
199
+ return validate(value) ? undefined : configErrors(validate.errors ?? [], value, dialectNames);
106
200
  }
201
+ /**
202
+ * Throws an error that says what is wrong when `value` is not a configuration
203
+ * that `configSchema` describes, naming each setting as it is written, as in
204
+ * `Invalid configuration: "extends[1]" must be a preset name, not 5`. Rule IDs,
205
+ * preset names, and rule options are checked when a document is processed.
206
+ */
107
207
  export function validateConfig(value) {
108
208
  const problem = configProblem(value);
109
209
  if (problem)
110
210
  throw new Error(`Invalid configuration: ${problem}`);
111
211
  }
212
+ const noOptions = Object.freeze({});
112
213
  export function setting(value) {
113
214
  return Array.isArray(value)
114
- ? { severity: value[0], options: value[1] }
115
- : { severity: value, options: {} };
215
+ ? { severity: value[0], options: value[1] ?? noOptions }
216
+ : { severity: value, options: noOptions };
217
+ }
218
+ /**
219
+ * Set each of `rules` in `target`. A rule named `__proto__` becomes a setting
220
+ * like any other, to be reported as unknown, instead of replacing the
221
+ * object's prototype as an assignment would.
222
+ */
223
+ function addRules(target, rules = {}) {
224
+ for (const [name, value] of Object.entries(rules))
225
+ Object.defineProperty(target, name, {
226
+ value,
227
+ enumerable: true,
228
+ writable: true,
229
+ configurable: true,
230
+ });
231
+ }
232
+ /** Settings that only a configuration has, which show a call in the prereleases' form. */
233
+ const configOnly = new Set(Object.keys(configSchema.properties).filter((key) => key !== "plugins"));
234
+ /**
235
+ * The matchers of override patterns, by pattern. A configuration is resolved
236
+ * for every document, and compiling its patterns each time cost several times
237
+ * as much as matching them.
238
+ */
239
+ const overridePatterns = new Map();
240
+ function overridePattern(pattern) {
241
+ let matches = overridePatterns.get(pattern);
242
+ if (!matches) {
243
+ // A process that loads many configurations keeps only recent patterns.
244
+ if (overridePatterns.size >= 1000)
245
+ overridePatterns.clear();
246
+ const matcher = new Minimatch(pattern, { dot: true });
247
+ matches = (file) => matcher.match(file);
248
+ overridePatterns.set(pattern, matches);
249
+ }
250
+ return matches;
116
251
  }
117
252
  /**
118
- * The configuration in effect for the document at `path`. `defaultDialect` is
119
- * the dialect to assume when neither the configuration, a preset, nor a
120
- * matching override names one: `github` unless the caller knows better, as the
121
- * CLI does at the root of an Obsidian vault.
253
+ * The configuration in effect for one document: its dialect, rule settings,
254
+ * `ignore` patterns, and `resolve` settings. It takes the `path`, `config`,
255
+ * `plugins`, and `defaultDialect` that `lint` and `format` take, so their
256
+ * options serve as they are. `defaultDialect` is the dialect to assume when
257
+ * neither the configuration, a preset, nor a matching override names one:
258
+ * `github` unless the caller knows better, as the CLI does inside an Obsidian
259
+ * vault. An invalid configuration or default dialect, an unknown preset, and a
260
+ * cycle of presets throw an error.
122
261
  */
123
- export function resolveConfig(config = {}, path = "document.md", plugins = [], defaultDialect = fallbackDialect) {
262
+ export function resolveConfig(options = {}) {
263
+ // The prereleases took the configuration, path, plugins, and default dialect one by one.
264
+ if (arguments.length > 1 ||
265
+ typeof options !== "object" ||
266
+ options === null ||
267
+ Object.keys(options).some((key) => configOnly.has(key)))
268
+ throw new TypeError("resolveConfig takes one options object, { path, config, plugins, defaultDialect }, since mdrefine 0.2.0.");
269
+ const { config = {}, path = "document.md", plugins = [] } = options;
124
270
  validateConfig(config);
125
- if (!dialects.includes(canonicalDialect(defaultDialect)))
126
- throw new Error(`Unknown default dialect: ${String(defaultDialect)}`);
271
+ const assumed = knownDialect(options.defaultDialect ?? fallbackDialect, "default dialect");
127
272
  const available = { ...presets };
128
273
  for (const plugin of plugins)
129
274
  for (const [name, preset] of Object.entries(plugin.presets ?? {}))
130
275
  available[`${plugin.name}/${name}`] = preset;
131
- const result = {
132
- dialect: canonicalDialect(defaultDialect),
133
- rules: {},
134
- ignore: [],
135
- resolve: {},
136
- };
276
+ const result = { dialect: assumed, rules: {}, ignore: [], resolve: {} };
137
277
  const overrides = [];
138
278
  function merge(part, chain) {
139
279
  validateConfig(part);
140
- for (const name of part.extends ?? []) {
280
+ for (const name of typeof part.extends === "string" ? [part.extends] : (part.extends ?? [])) {
141
281
  if (chain.includes(name))
142
282
  throw new Error(`Circular preset: ${[...chain, name].join(" -> ")}`);
143
- const preset = available[name];
144
- if (!preset)
283
+ // Names such as `toString` are found on every object; only defined presets count.
284
+ if (!Object.hasOwn(available, name))
145
285
  throw new Error(`Unknown preset: ${name}`);
146
- merge(preset, [...chain, name]);
286
+ merge(available[name], [...chain, name]);
147
287
  }
148
288
  if (part.dialect)
149
289
  result.dialect = canonicalDialect(part.dialect);
150
- Object.assign(result.rules, part.rules);
290
+ addRules(result.rules, part.rules);
151
291
  Object.assign(result.resolve, part.resolve);
152
292
  result.ignore.push(...(part.ignore ?? []));
153
293
  overrides.push(...(part.overrides ?? []));
@@ -155,11 +295,12 @@ export function resolveConfig(config = {}, path = "document.md", plugins = [], d
155
295
  if (config.extends === undefined)
156
296
  merge(presets.recommended, []);
157
297
  merge(config, []);
298
+ const document = path.replaceAll("\\", "/");
158
299
  for (const override of overrides) {
159
- if (override.files.some((pattern) => minimatch(path.replaceAll("\\", "/"), pattern, { dot: true }))) {
300
+ if (override.files.some((pattern) => overridePattern(pattern)(document))) {
160
301
  if (override.dialect)
161
302
  result.dialect = canonicalDialect(override.dialect);
162
- Object.assign(result.rules, override.rules);
303
+ addRules(result.rules, override.rules);
163
304
  }
164
305
  }
165
306
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv } from \"ajv\";\nimport { minimatch } from \"minimatch\";\nimport type {\n Config,\n Dialect,\n DialectName,\n Plugin,\n ResolvedConfig,\n RuleSetting,\n} from \"../core/types.js\";\n\n/** Alias names that select an existing dialect; Codeberg runs Forgejo's renderer. */\nexport const dialectAliases: Record<string, Dialect> = { codeberg: \"forgejo\" };\nexport const dialects: Dialect[] = [\"commonmark\", \"github\", \"forgejo\", \"gitea\", \"obsidian\"];\n/**\n * The dialect assumed when nothing names one and the caller knows no better.\n * GitHub's syntax is the common base of the Forgejo, Gitea, and Obsidian\n * dialects, so a table or a footnote written for any of them is not read as an\n * ordinary paragraph and reflowed.\n */\nexport const fallbackDialect: Dialect = \"github\";\nexport function canonicalDialect(name: DialectName): Dialect {\n return dialectAliases[name] ?? (name as Dialect);\n}\n\nexport const presets: Record<string, Config> = {\n recommended: {\n rules: {\n \"style/wrap\": [\"warn\", { width: 80 }],\n \"style/emphasis\": [\"warn\", { marker: \"_\" }],\n \"style/strong\": [\"warn\", { marker: \"*\" }],\n \"style/final-newline\": \"warn\",\n \"links/valid\": \"error\",\n },\n },\n github: {\n dialect: \"github\",\n rules: { \"github/task-marker\": \"warn\", \"github/alert-marker\": \"warn\", \"style/table\": \"warn\" },\n },\n forgejo: {\n dialect: \"forgejo\",\n rules: {\n \"github/task-marker\": \"warn\",\n \"github/alert-marker\": \"warn\",\n \"style/table\": \"warn\",\n \"forgejo/heading-id\": \"error\",\n },\n },\n codeberg: { extends: [\"forgejo\"] },\n gitea: {\n dialect: \"gitea\",\n rules: {\n \"github/task-marker\": \"warn\",\n \"github/alert-marker\": \"warn\",\n \"style/table\": \"warn\",\n \"forgejo/heading-id\": \"error\",\n },\n },\n obsidian: {\n dialect: \"obsidian\",\n rules: {\n \"obsidian/callout-marker\": \"warn\",\n \"obsidian/block-reference\": \"error\",\n \"obsidian/strict-line-breaks\": \"warn\",\n \"github/task-marker\": \"warn\",\n \"style/table\": \"warn\",\n },\n },\n};\nconst severity = { enum: [\"off\", \"warn\", \"error\"] };\nconst dialect = { enum: [...dialects, ...Object.keys(dialectAliases)] };\nconst rules = {\n type: \"object\",\n additionalProperties: {\n anyOf: [\n severity,\n { type: \"array\", items: [severity, { type: \"object\" }], minItems: 2, maxItems: 2 },\n ],\n },\n};\nexport const configSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n additionalProperties: false,\n properties: {\n $schema: { type: \"string\" },\n resolve: {\n type: \"object\",\n additionalProperties: false,\n properties: { gitIgnored: { type: \"boolean\" }, nestedRepositories: { type: \"boolean\" } },\n },\n extends: { type: \"array\", items: { type: \"string\" } },\n dialect,\n rules,\n ignore: { type: \"array\", items: { type: \"string\" } },\n plugins: { type: \"array\", items: { type: \"string\" } },\n overrides: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"files\"],\n additionalProperties: false,\n properties: {\n files: { type: \"array\", items: { type: \"string\" }, minItems: 1 },\n dialect,\n rules,\n },\n },\n },\n },\n};\nconst validate = new Ajv({ allErrors: true }).compile(configSchema);\n/** What is wrong with `value` as a configuration, or undefined when it is valid. */\nexport function configProblem(value: unknown): string | undefined {\n return validate(value) ? undefined : new Ajv().errorsText(validate.errors);\n}\nexport function validateConfig(value: unknown): asserts value is Config {\n const problem = configProblem(value);\n if (problem) throw new Error(`Invalid configuration: ${problem}`);\n}\nexport function setting(value: RuleSetting): {\n severity: \"off\" | \"warn\" | \"error\";\n options: Record<string, unknown>;\n} {\n return Array.isArray(value)\n ? { severity: value[0], options: value[1] }\n : { severity: value, options: {} };\n}\n/**\n * The configuration in effect for the document at `path`. `defaultDialect` is\n * the dialect to assume when neither the configuration, a preset, nor a\n * matching override names one: `github` unless the caller knows better, as the\n * CLI does at the root of an Obsidian vault.\n */\nexport function resolveConfig(\n config: Config = {},\n path = \"document.md\",\n plugins: Plugin[] = [],\n defaultDialect: DialectName = fallbackDialect,\n): ResolvedConfig {\n validateConfig(config);\n if (!dialects.includes(canonicalDialect(defaultDialect)))\n throw new Error(`Unknown default dialect: ${String(defaultDialect)}`);\n const available = { ...presets };\n for (const plugin of plugins)\n for (const [name, preset] of Object.entries(plugin.presets ?? {}))\n available[`${plugin.name}/${name}`] = preset;\n const result: ResolvedConfig = {\n dialect: canonicalDialect(defaultDialect),\n rules: {},\n ignore: [],\n resolve: {},\n };\n const overrides: NonNullable<Config[\"overrides\"]> = [];\n function merge(part: Config, chain: string[]) {\n validateConfig(part);\n for (const name of part.extends ?? []) {\n if (chain.includes(name))\n throw new Error(`Circular preset: ${[...chain, name].join(\" -> \")}`);\n const preset = available[name];\n if (!preset) throw new Error(`Unknown preset: ${name}`);\n merge(preset, [...chain, name]);\n }\n if (part.dialect) result.dialect = canonicalDialect(part.dialect);\n Object.assign(result.rules, part.rules);\n Object.assign(result.resolve, part.resolve);\n result.ignore.push(...(part.ignore ?? []));\n overrides.push(...(part.overrides ?? []));\n }\n if (config.extends === undefined) merge(presets.recommended!, []);\n merge(config, []);\n for (const override of overrides) {\n if (\n override.files.some((pattern) =>\n minimatch(path.replaceAll(\"\\\\\", \"/\"), pattern, { dot: true }),\n )\n ) {\n if (override.dialect) result.dialect = canonicalDialect(override.dialect);\n Object.assign(result.rules, override.rules);\n }\n }\n return result;\n}\n"]}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import { Ajv } from \"ajv\";\nimport { Minimatch } from \"minimatch\";\nimport { configErrors } from \"./problems.js\";\nimport { deepFreeze } from \"../core/frozen.js\";\nimport type {\n Config,\n Dialect,\n DialectName,\n JsonSchemaObject,\n ResolveConfigOptions,\n ResolvedConfig,\n RuleSetting,\n} from \"../core/types.js\";\n\n/**\n * Alias names that select an existing dialect, mapped to that dialect:\n * Codeberg runs Forgejo's renderer. The table is frozen.\n */\nexport const dialectAliases: Readonly<Record<Exclude<DialectName, Dialect>, Dialect>> =\n Object.freeze({ codeberg: \"forgejo\" });\n/** The dialects, in the order the documentation lists them. The list is frozen. */\nexport const dialects: readonly Dialect[] = Object.freeze([\n \"commonmark\",\n \"github\",\n \"forgejo\",\n \"gitea\",\n \"obsidian\",\n]);\n/**\n * The dialect assumed when nothing names one and the caller knows no better.\n * GitHub's syntax is the common base of the Forgejo, Gitea, and Obsidian\n * dialects, so a table or a footnote written for any of them is not read as an\n * ordinary paragraph and reflowed.\n */\nexport const fallbackDialect: Dialect = \"github\";\n/**\n * The dialect that `name` stands for: an alias's dialect, or `name` itself.\n * A name that is neither is returned as it is.\n */\nexport function canonicalDialect(name: DialectName): Dialect {\n return Object.hasOwn(dialectAliases, name)\n ? dialectAliases[name as keyof typeof dialectAliases]\n : (name as Dialect);\n}\n/** The dialect that `name` stands for, or an error that says what was named. */\nexport function knownDialect(name: DialectName, what = \"dialect\"): Dialect {\n const dialect = canonicalDialect(name);\n if (!dialects.includes(dialect)) throw new Error(`Unknown ${what}: ${String(name)}`);\n return dialect;\n}\n\n/**\n * The built-in presets by name. The table and everything in it are frozen, so\n * that no caller can change what another one gets.\n */\nexport const presets: Readonly<Record<string, Readonly<Config>>> = {\n recommended: {\n rules: {\n \"style/wrap\": [\"warn\", { width: 80 }],\n \"style/emphasis\": [\"warn\", { marker: \"_\" }],\n \"style/strong\": [\"warn\", { marker: \"*\" }],\n \"style/heading\": \"warn\",\n \"style/table\": \"warn\",\n \"style/code-fence\": \"warn\",\n \"style/thematic-break\": \"warn\",\n \"style/blank-lines\": \"warn\",\n \"style/trailing-space\": \"warn\",\n \"style/final-newline\": \"warn\",\n \"style/list-marker\": [\"warn\", { marker: \"-\" }],\n \"style/ordered-list\": [\"warn\", { delimiter: \".\", numbering: \"auto\" }],\n \"style/list-indent\": \"warn\",\n \"links/valid\": \"error\",\n \"links/undefined-reference\": \"warn\",\n \"links/unused-definition\": \"warn\",\n \"links/empty\": \"warn\",\n \"structure/heading-increment\": \"warn\",\n \"content/image-alt\": \"warn\",\n \"content/table-columns\": \"warn\",\n },\n },\n github: {\n dialect: \"github\",\n rules: { \"github/task-marker\": \"warn\", \"github/alert-marker\": \"warn\", \"style/table\": \"warn\" },\n },\n forgejo: {\n dialect: \"forgejo\",\n rules: {\n \"github/task-marker\": \"warn\",\n \"github/alert-marker\": \"warn\",\n \"style/table\": \"warn\",\n \"forgejo/heading-id\": \"error\",\n },\n },\n codeberg: { extends: [\"forgejo\"] },\n gitea: {\n dialect: \"gitea\",\n rules: {\n \"github/task-marker\": \"warn\",\n \"github/alert-marker\": \"warn\",\n \"style/table\": \"warn\",\n \"forgejo/heading-id\": \"error\",\n },\n },\n obsidian: {\n dialect: \"obsidian\",\n rules: {\n \"obsidian/callout-marker\": \"warn\",\n \"obsidian/block-reference\": \"error\",\n \"obsidian/strict-line-breaks\": \"warn\",\n \"github/task-marker\": \"warn\",\n \"style/table\": \"warn\",\n },\n },\n};\ndeepFreeze(presets);\n// Each dialect is followed by its aliases, as the command line lists them.\nconst dialectNames = dialects.flatMap((dialect) => [\n dialect,\n ...Object.entries(dialectAliases).flatMap(([alias, of]) => (of === dialect ? [alias] : [])),\n]);\nconst strings = { type: \"array\", items: { type: \"string\" } };\n/**\n * The configuration's JSON Schema, which `validateConfig` enforces. The\n * package ships it as `config.schema.json`, which a test keeps equal to it,\n * and the documentation site serves it for editors.\n */\nexport const configSchema: JsonSchemaObject = deepFreeze({\n $schema: \"http://json-schema.org/draft-07/schema#\",\n title: \"mdtools configuration\",\n description:\n \"Configuration of the mdtools command of mdrefine: https://viell-dev.github.io/slop-markdown-tools/configuration.html\",\n type: \"object\",\n additionalProperties: false,\n properties: {\n $schema: { description: \"The JSON Schema for editors; the tool ignores it.\", type: \"string\" },\n resolve: {\n description: \"Files that links may lead to, which are never linted or formatted.\",\n type: \"object\",\n additionalProperties: false,\n properties: {\n gitIgnored: {\n description: \"Files that .gitignore files exclude are link targets. Default: false.\",\n type: \"boolean\",\n },\n nestedRepositories: {\n description: \"Files of nested Git repositories are link targets. Default: false.\",\n type: \"boolean\",\n },\n },\n },\n extends: {\n description:\n \"Presets to start from, in order: a preset name or a list of them. Without it, the configuration starts from recommended.\",\n anyOf: [{ type: \"string\" }, strings],\n },\n dialect: { $ref: \"#/definitions/dialect\" },\n rules: { $ref: \"#/definitions/rules\" },\n ignore: {\n description:\n \"Path patterns of documents that are never linted or formatted, matched with their letter case. They stay link targets.\",\n ...strings,\n },\n plugins: {\n description: \"Plugins to load: files relative to this file, or package names.\",\n ...strings,\n },\n overrides: {\n description: \"Settings for the documents that match one of the patterns in files.\",\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"files\"],\n additionalProperties: false,\n properties: {\n files: {\n description:\n \"Path patterns, matched with their letter case against paths relative to the workspace root.\",\n ...strings,\n minItems: 1,\n },\n dialect: { $ref: \"#/definitions/dialect\" },\n rules: { $ref: \"#/definitions/rules\" },\n },\n },\n },\n },\n definitions: {\n dialect: {\n description:\n \"The renderer whose syntax documents are read in. When nothing names one, github is assumed, or obsidian inside a vault.\",\n enum: dialectNames,\n },\n severity: { enum: [\"off\", \"warn\", \"error\"] },\n rules: {\n description:\n 'Rule IDs and their settings: a severity, or a list of a severity and the rule\\'s options, as in [\"warn\", { \"width\": 100 }].',\n type: \"object\",\n additionalProperties: {\n anyOf: [\n { $ref: \"#/definitions/severity\" },\n { type: \"array\", items: [{ $ref: \"#/definitions/severity\" }], minItems: 1, maxItems: 1 },\n {\n type: \"array\",\n items: [{ $ref: \"#/definitions/severity\" }, { type: \"object\" }],\n minItems: 2,\n maxItems: 2,\n },\n ],\n },\n },\n },\n});\nconst validate = new Ajv({ allErrors: true }).compile(configSchema);\n/** What is wrong with `value` as a configuration, in plain words, or undefined when it is valid. */\nexport function configProblem(value: unknown): string | undefined {\n return validate(value) ? undefined : configErrors(validate.errors ?? [], value, dialectNames);\n}\n/**\n * Throws an error that says what is wrong when `value` is not a configuration\n * that `configSchema` describes, naming each setting as it is written, as in\n * `Invalid configuration: \"extends[1]\" must be a preset name, not 5`. Rule IDs,\n * preset names, and rule options are checked when a document is processed.\n */\nexport function validateConfig(value: unknown): asserts value is Config {\n const problem = configProblem(value);\n if (problem) throw new Error(`Invalid configuration: ${problem}`);\n}\nconst noOptions: Readonly<Record<string, unknown>> = Object.freeze({});\nexport function setting(value: RuleSetting): {\n severity: \"off\" | \"warn\" | \"error\";\n options: Readonly<Record<string, unknown>>;\n} {\n return Array.isArray(value)\n ? { severity: value[0], options: value[1] ?? noOptions }\n : { severity: value as Exclude<RuleSetting, readonly unknown[]>, options: noOptions };\n}\n/**\n * Set each of `rules` in `target`. A rule named `__proto__` becomes a setting\n * like any other, to be reported as unknown, instead of replacing the\n * object's prototype as an assignment would.\n */\nfunction addRules(target: Record<string, RuleSetting>, rules: Config[\"rules\"] = {}) {\n for (const [name, value] of Object.entries(rules))\n Object.defineProperty(target, name, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n}\n/** Settings that only a configuration has, which show a call in the prereleases' form. */\nconst configOnly = new Set(\n Object.keys(configSchema.properties as object).filter((key) => key !== \"plugins\"),\n);\n/**\n * The matchers of override patterns, by pattern. A configuration is resolved\n * for every document, and compiling its patterns each time cost several times\n * as much as matching them.\n */\nconst overridePatterns = new Map<string, (file: string) => boolean>();\nfunction overridePattern(pattern: string): (file: string) => boolean {\n let matches = overridePatterns.get(pattern);\n if (!matches) {\n // A process that loads many configurations keeps only recent patterns.\n if (overridePatterns.size >= 1000) overridePatterns.clear();\n const matcher = new Minimatch(pattern, { dot: true });\n matches = (file) => matcher.match(file);\n overridePatterns.set(pattern, matches);\n }\n return matches;\n}\n/**\n * The configuration in effect for one document: its dialect, rule settings,\n * `ignore` patterns, and `resolve` settings. It takes the `path`, `config`,\n * `plugins`, and `defaultDialect` that `lint` and `format` take, so their\n * options serve as they are. `defaultDialect` is the dialect to assume when\n * neither the configuration, a preset, nor a matching override names one:\n * `github` unless the caller knows better, as the CLI does inside an Obsidian\n * vault. An invalid configuration or default dialect, an unknown preset, and a\n * cycle of presets throw an error.\n */\nexport function resolveConfig(options: ResolveConfigOptions = {}): ResolvedConfig {\n // The prereleases took the configuration, path, plugins, and default dialect one by one.\n if (\n arguments.length > 1 ||\n typeof options !== \"object\" ||\n options === null ||\n Object.keys(options).some((key) => configOnly.has(key))\n )\n throw new TypeError(\n \"resolveConfig takes one options object, { path, config, plugins, defaultDialect }, since mdrefine 0.2.0.\",\n );\n const { config = {}, path = \"document.md\", plugins = [] } = options;\n validateConfig(config);\n const assumed = knownDialect(options.defaultDialect ?? fallbackDialect, \"default dialect\");\n const available: Record<string, Readonly<Config>> = { ...presets };\n for (const plugin of plugins)\n for (const [name, preset] of Object.entries(plugin.presets ?? {}))\n available[`${plugin.name}/${name}`] = preset;\n const result: ResolvedConfig = { dialect: assumed, rules: {}, ignore: [], resolve: {} };\n const overrides: NonNullable<Config[\"overrides\"]>[number][] = [];\n function merge(part: Readonly<Config>, chain: readonly string[]) {\n validateConfig(part);\n for (const name of typeof part.extends === \"string\" ? [part.extends] : (part.extends ?? [])) {\n if (chain.includes(name))\n throw new Error(`Circular preset: ${[...chain, name].join(\" -> \")}`);\n // Names such as `toString` are found on every object; only defined presets count.\n if (!Object.hasOwn(available, name)) throw new Error(`Unknown preset: ${name}`);\n merge(available[name]!, [...chain, name]);\n }\n if (part.dialect) result.dialect = canonicalDialect(part.dialect);\n addRules(result.rules, part.rules);\n Object.assign(result.resolve, part.resolve);\n result.ignore.push(...(part.ignore ?? []));\n overrides.push(...(part.overrides ?? []));\n }\n if (config.extends === undefined) merge(presets.recommended!, []);\n merge(config, []);\n const document = path.replaceAll(\"\\\\\", \"/\");\n for (const override of overrides) {\n if (override.files.some((pattern) => overridePattern(pattern)(document))) {\n if (override.dialect) result.dialect = canonicalDialect(override.dialect);\n addRules(result.rules, override.rules);\n }\n }\n return result;\n}\n"]}
@@ -1,3 +1,10 @@
1
1
  import type { Document, Finding } from "./types.js";
2
+ /** A suppression directive and the rules it names, `*` for all of them. */
3
+ export interface Directive {
4
+ kind: "disable-next-line" | "disable" | "enable";
5
+ rules: Set<string>;
6
+ }
7
+ /** The directive that an HTML node's value holds, if it is one. */
8
+ export declare function directive(value: string): Directive | undefined;
2
9
  /** Directives are recognized only in parsed HTML comments, never in code examples. */
3
10
  export declare function suppressions(document: Document): (rule: string, finding: Finding) => boolean;