diff --git a/.npmrc b/.npmrc index f74c8b1..4df60bb 100644 --- a/.npmrc +++ b/.npmrc @@ -10,4 +10,5 @@ public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*knip* public-hoist-pattern[]=*mdat* public-hoist-pattern[]=*prettier* +public-hoist-pattern[]=*remark* public-hoist-pattern[]=*stylelint* diff --git a/.remarkrc.js b/.remarkrc.js new file mode 100644 index 0000000..1e87e12 --- /dev/null +++ b/.remarkrc.js @@ -0,0 +1,3 @@ +import { remarkConfig } from '@envsa/remark-config'; + +export default remarkConfig(); diff --git a/package.json b/package.json index be5b761..2948bb1 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "prettier-config", "browserslist-config", "typescript-config", + "remark-config", + "remark-lint", "github-actions", "cspell", "tsconfig", @@ -52,6 +54,7 @@ "@envsa/eslint-config": "workspace:*", "@envsa/mdat-config": "workspace:*", "@envsa/prettier-config": "workspace:*", + "@envsa/remark-config": "workspace:*", "@envsa/repo-config": "workspace:*", "@envsa/shared-config": "workspace:*", "@envsa/stylelint-config": "workspace:*", diff --git a/packages/browserslist-config/readme.md b/packages/browserslist-config/readme.md index 5a58ae6..7a924fa 100644 --- a/packages/browserslist-config/readme.md +++ b/packages/browserslist-config/readme.md @@ -25,7 +25,7 @@ It's a shared [Browserslist](https://browsersl.ist) config. -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > diff --git a/packages/cspell-config/dictionaries/envsa-misc.txt b/packages/cspell-config/dictionaries/envsa-misc.txt index 695a46f..712e936 100644 --- a/packages/cspell-config/dictionaries/envsa-misc.txt +++ b/packages/cspell-config/dictionaries/envsa-misc.txt @@ -365,6 +365,8 @@ redactorcustomstyles relatedsub rella rellafella +remarklint +remarkrc renmark renxt retcon diff --git a/packages/cspell-config/readme.md b/packages/cspell-config/readme.md index d6ef08d..a69b19f 100644 --- a/packages/cspell-config/readme.md +++ b/packages/cspell-config/readme.md @@ -25,7 +25,7 @@ It's a shared [CSpell](https://cspell.org) config, plus a command-line tool `env -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > @@ -52,7 +52,7 @@ To use just this CSpell config in isolation: 3. Add the starter `.cspell.json` file to your project root, and add any customizations you'd like: ```sh - pnpm exec kpi-cspell init + pnpm exec envsa-cspell init ``` ## Usage diff --git a/packages/eslint-config/readme.md b/packages/eslint-config/readme.md index 786dd95..ef13ec3 100644 --- a/packages/eslint-config/readme.md +++ b/packages/eslint-config/readme.md @@ -25,7 +25,7 @@ It's a shared [ESLint](https://eslint.org) config, plus a command-line tool `env -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > diff --git a/packages/eslint-config/src/configs/json.ts b/packages/eslint-config/src/configs/json.ts index eb73803..32350e8 100644 --- a/packages/eslint-config/src/configs/json.ts +++ b/packages/eslint-config/src/configs/json.ts @@ -92,6 +92,7 @@ export async function json(options: OptionsOverrides = {}): Promise -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > diff --git a/packages/knip-config/src/index.ts b/packages/knip-config/src/index.ts index 99038b3..0091c8e 100644 --- a/packages/knip-config/src/index.ts +++ b/packages/knip-config/src/index.ts @@ -13,6 +13,7 @@ const sharedKnipConfig: KnipConfig = { // Customized entries 'src/{bin,lib,cli}/{index,cli,main}.{js,mjs,cjs,ts,mts,cts}!', 'scripts/**/*.ts', + '.remarkrc.js', 'cspell.config.js', 'eslint.config.ts', 'mdat.config.ts', @@ -25,6 +26,7 @@ const sharedKnipConfig: KnipConfig = { '@envsa/knip-config', '@envsa/mdat-config', '@envsa/prettier-config', + '@envsa/remark-config', '@envsa/stylelint-config', ], }; diff --git a/packages/mdat-config/readme.md b/packages/mdat-config/readme.md index b082c90..9707920 100644 --- a/packages/mdat-config/readme.md +++ b/packages/mdat-config/readme.md @@ -25,7 +25,7 @@ It's a shared [MDAT (Markdown Autophagic Template)](https://github.com/kitschpat -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > diff --git a/packages/prettier-config/readme.md b/packages/prettier-config/readme.md index e0d7de9..82e5b60 100644 --- a/packages/prettier-config/readme.md +++ b/packages/prettier-config/readme.md @@ -25,7 +25,7 @@ It's a shared [Prettier](https://prettier.io) config, plus a command-line tool ` -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > diff --git a/packages/prettier-config/src/index.ts b/packages/prettier-config/src/index.ts index 8029e02..ae0d5f5 100644 --- a/packages/prettier-config/src/index.ts +++ b/packages/prettier-config/src/index.ts @@ -82,6 +82,7 @@ const sharedPrettierConfig: PrettierConfig = { 'knip', 'mdat', 'prettier', + 'remarkConfig', 'stylelint', ]), }, diff --git a/packages/remark-config/init/.remarkrc.js b/packages/remark-config/init/.remarkrc.js new file mode 100644 index 0000000..1e87e12 --- /dev/null +++ b/packages/remark-config/init/.remarkrc.js @@ -0,0 +1,3 @@ +import { remarkConfig } from '@envsa/remark-config'; + +export default remarkConfig(); diff --git a/packages/remark-config/init/.vscode/extensions.json b/packages/remark-config/init/.vscode/extensions.json new file mode 100644 index 0000000..857ed16 --- /dev/null +++ b/packages/remark-config/init/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["unifiedjs.vscode-mdx"] +} diff --git a/packages/remark-config/license.txt b/packages/remark-config/license.txt new file mode 100644 index 0000000..baec81f --- /dev/null +++ b/packages/remark-config/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-2025 Liam Rella + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/remark-config/package.json b/packages/remark-config/package.json new file mode 100644 index 0000000..e61d4a9 --- /dev/null +++ b/packages/remark-config/package.json @@ -0,0 +1,102 @@ +{ + "name": "@envsa/remark-config", + "version": "5.0.5", + "description": "Markdown and MDX linting for @envsa/shared-config.", + "keywords": [ + "shared-config", + "remark-config", + "remark-lint", + "remark", + "cli", + "envsa", + "envsa-remark" + ], + "homepage": "https://github.com/envsa/shared-config/tree/main/packages/remark-config", + "bugs": "https://github.com/envsa/shared-config/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/envsa/shared-config.git", + "directory": "packages/remark-config" + }, + "license": "MIT", + "author": { + "name": "Liam Rella", + "url": "https://github.com/rellafella" + }, + "type": "module", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "bin": { + "envsa-remark": "bin/cli.js" + }, + "files": [ + "bin/*", + "dist/*", + "init/*" + ], + "scripts": { + "build": "tsc && ../../scripts/build.ts", + "cli": "node ./bin/cli.js", + "prepublishOnly": "pnpm run build" + }, + "dependencies": { + "@pinojs/json-colorizer": "^4.0.0", + "@types/mdast": "^4.0.4", + "cosmiconfig": "^9.0.0", + "execa": "^9.5.2", + "find-workspaces": "^0.3.1", + "fs-extra": "^11.3.0", + "mdast-util-to-markdown": "^2.1.2", + "prettier": "^3.5.0", + "remark-directive": "^3.0.1", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "remark-lint": "^10.0.1", + "remark-lint-checkbox-content-indent": "^5.0.1", + "remark-lint-fenced-code-flag": "^4.1.1", + "remark-lint-final-definition": "^4.0.2", + "remark-lint-first-heading-level": "^4.0.1", + "remark-lint-heading-increment": "^4.0.1", + "remark-lint-linebreak-style": "^4.0.1", + "remark-lint-maximum-heading-length": "^4.1.1", + "remark-lint-no-duplicate-defined-urls": "^3.0.1", + "remark-lint-no-duplicate-definitions": "^4.0.1", + "remark-lint-no-duplicate-headings": "^4.0.1", + "remark-lint-no-duplicate-headings-in-section": "^4.0.1", + "remark-lint-no-empty-url": "^4.0.1", + "remark-lint-no-file-name-articles": "^3.0.1", + "remark-lint-no-file-name-consecutive-dashes": "^3.0.1", + "remark-lint-no-file-name-irregular-characters": "^3.0.1", + "remark-lint-no-file-name-outer-dashes": "^3.0.1", + "remark-lint-no-heading-indent": "^5.0.1", + "remark-lint-no-heading-like-paragraph": "^4.0.1", + "remark-lint-no-multiple-toplevel-headings": "^4.0.1", + "remark-lint-no-paragraph-content-indent": "^5.0.1", + "remark-lint-no-reference-like-url": "^4.0.1", + "remark-lint-no-shell-dollars": "^4.0.1", + "remark-lint-no-shortcut-reference-image": "^4.0.1", + "remark-lint-no-shortcut-reference-link": "^4.0.1", + "remark-lint-no-tabs": "^4.0.1", + "remark-lint-no-undefined-references": "^5.0.1", + "remark-lint-no-unneeded-full-reference-image": "^4.0.1", + "remark-lint-no-unneeded-full-reference-link": "^4.0.1", + "remark-lint-no-unused-definitions": "^4.0.1", + "remark-lint-strikethrough-marker": "^3.0.1", + "remark-stringify": "^11.0.0", + "remark-validate-links": "^13.0.2", + "unified": "^11.0.5" + }, + "engines": { + "node": ">=22.0.0", + "pnpm": ">=10.0.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/remark-config/readme.md b/packages/remark-config/readme.md new file mode 100644 index 0000000..1a70a32 --- /dev/null +++ b/packages/remark-config/readme.md @@ -0,0 +1,173 @@ + + + + +# @envsa/remark-config + + + + + +[![NPM Package @envsa/remark-config](https://img.shields.io/npm/v/@envsa/remark-config.svg)](https://npmjs.com/package/@envsa/remark-config) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + + + + + +**Markdown and MDX linting for @envsa/shared-config.** + + + +## Overview + +It's a shared [Remark](https://github.com/remarkjs/remark/blob/main/packages/remark-cli/readme.md#example-config-files-json-yaml-js) config for linting Markdown and MDX files, plus a command-line tool `envsa-remark` to streamline project initialization. Note that linting and fixing is provided separately through [@envsa/eslint-config](https://github.com/envsa/shared-config/tree/main/packages/eslint-config). + + + +> [!IMPORTANT] +> +> **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** +> +> This package is included as a dependency in [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config), which also automatically invokes the command line functionality in this package via its `envsa` command + + + +## Setup + +To use just this Remark config in isolation: + +1. Install the `.npmrc` in your project root. This is required for correct PNPM behavior: + + ```sh + pnpm dlx @envsa/repo-config init + ``` + +2. Add the package: + + ```sh + pnpm add -D @envsa/remark-config + ``` + +3. Add the starter `.remarkrc.js` and files to your project root, and add any customizations you'd like: + + ```sh + pnpm exec envsa-remark init + ``` + +## Usage + +The Remark binary should be picked up automatically by VS Code plugins. + +You can call it directly, but it's recommended to use the `envsa` script bundled with the [@envsa/shared-config](https://github.com/envsa/shared-config) instead to invoke the Remark lint rules through ESLint. The [`eslint-mdx`](https://github.com/mdx-js/eslint-mdx) plugin is used to bridge these rules into ESLint and the VS Code ESLint plugin. + +If you really want to call it directly, you can integrate a command to the underlying `remark` CLI tool with your `package.json` scripts as you see fit, for example: + +```json +{ + "scripts": { + "lint": "pnpm remark . --quiet --frail" + } +} +``` + +### CLI + + + +#### Command: `envsa-remark` + +Envsa's Remark and Remark Lint shared configuration tools. (Actual linting and fixing is managed through @envsa/eslint-config.) + +This section lists top-level commands for `envsa-remark`. + +Usage: + +```txt +envsa-remark +``` + +| Command | Description | +| -------------- | ------------------------------------------------------------------------------------------------------------- | +| `init` | Initialize by copying starter config files to your project root or to your package.json file. | +| `print-config` | Print the effective Remark configuration. Package-scoped. Searches up to the root of a monorepo if necessary. | + +| Option | Description | Type | +| ------------------- | ------------------- | --------- | +| `--help`
`-h` | Show help | `boolean` | +| `--version`
`-v` | Show version number | `boolean` | + +_See the sections below for more information on each subcommand._ + +#### Subcommand: `envsa-remark init` + +Initialize by copying starter config files to your project root or to your package.json file. + +Usage: + +```txt +envsa-remark init +``` + +| Option | Description | Type | Default | +| ------------------- | ------------------- | -------------------- | -------- | +| `--location` | TK | `"file"` `"package"` | `"file"` | +| `--help`
`-h` | Show help | `boolean` | | +| `--version`
`-v` | Show version number | `boolean` | | + +#### Subcommand: `envsa-remark print-config` + +Print the effective Remark configuration. Package-scoped. Searches up to the root of a monorepo if necessary. + +Usage: + +```txt +envsa-remark print-config +``` + +| Option | Description | Type | +| ------------------- | ------------------- | --------- | +| `--help`
`-h` | Show help | `boolean` | +| `--version`
`-v` | Show version number | `boolean` | + + + +## Configuration + +### Avoiding errors in non-git projects + +The [remark-validate-links](https://github.com/remarkjs/remark-validate-links) looks for a git remote to validate relative link paths. + +If your project is not a git repository, you will receive warning from remark via eslint: + +```txt +Command failed: git remote -v +fatal: not a git repository (or any of the parent directories): .git +eslint(undefined-undefined) +``` + +To fix this, pass the `repository: false` option in your `.remarkrc.js` file: + +```js +// .remarkrc.js +import sharedConfig, { overrideRules } from '@envsa/remark-config'; + +const localConfig = { + ...sharedConfig, + plugins: overrideRules(sharedConfig.plugins, [['remarkValidateLinks', { repository: false }]]), +}; + +export default localConfig; +``` + +## Credits + +[Eric Mika](https://github.com/kitschpatrol) is the author of the original [@kitschpatrol/shared-config](https://github.com/kitschpatrol/shared-config) project on which this is based. + + + +## License + +[MIT](license.txt) © Liam Rella + + diff --git a/packages/remark-config/src/cli.ts b/packages/remark-config/src/cli.ts new file mode 100755 index 0000000..b2c55d8 --- /dev/null +++ b/packages/remark-config/src/cli.ts @@ -0,0 +1,5 @@ +#!/usr/bin/env node +import { buildCommands } from '../../../src/command-builder.js'; +import { commandDefinition } from './command.js'; + +await buildCommands(commandDefinition); diff --git a/packages/remark-config/src/command.ts b/packages/remark-config/src/command.ts new file mode 100644 index 0000000..f1b479d --- /dev/null +++ b/packages/remark-config/src/command.ts @@ -0,0 +1,31 @@ +import { + type CommandDefinition, + DESCRIPTION, + getCosmiconfigCommand, +} from '../../../src/command-builder.js'; + +export const commandDefinition: CommandDefinition = { + commands: { + init: { + // Note that remark.config.js is not detected by the config resolver ಠ_ಠ + configFile: '.remarkrc.js', + configPackageJson: { + remarkConfig: { + plugins: ['@envsa/remark-config'], + }, + }, + locationOptionFlag: true, + }, + printConfig: { + commands: [getCosmiconfigCommand('remark')], + description: `Print the effective Remark configuration. ${DESCRIPTION.packageSearch} ${DESCRIPTION.monorepoSearch}`, + positionalArgumentMode: 'none', + }, + }, + description: + "Envsa's Remark and Remark Lint shared configuration tools. (Actual linting and fixing is managed through @envsa/eslint-config.)", + logColor: 'blue', + logPrefix: '[remarklint]', + name: 'envsa-remark', + order: 8, +}; diff --git a/packages/remark-config/src/index.ts b/packages/remark-config/src/index.ts new file mode 100644 index 0000000..a0783fd --- /dev/null +++ b/packages/remark-config/src/index.ts @@ -0,0 +1,287 @@ +import type { Parents, Text } from 'mdast'; +import type { Info, State } from 'mdast-util-to-markdown'; +import type { Pluggable, PluggableList, Preset as RemarkConfig } from 'unified'; +import { defaultHandlers as mdastToTextHandlers } from 'mdast-util-to-markdown'; +import remarkDirective from 'remark-directive'; +import remarkFrontmatter from 'remark-frontmatter'; +import remarkGfm from 'remark-gfm'; +import remarkLint from 'remark-lint'; +import remarkValidateLinks from 'remark-validate-links'; +// export { commandDefinition } from './command.js' + +// Necessary for side-effect type definitions? +import 'remark-stringify'; + +// See https://github.com/remarkjs/remark-lint?tab=readme-ov-file#rules +// Official +import remarkLintCheckboxContentIndent from 'remark-lint-checkbox-content-indent'; // Warn when too much whitespace follows list item checkboxes +// import remarkLintCorrectMediaSyntax from 'remark-lint-correct-media-syntax' // Check for accidental bracket and paren mixup for images and links +// import remarkLintDefinitionSort from 'remark-lint-definition-sort' // Check definition order +// import remarkLintDirectiveAttributeSort from 'remark-lint-directive-attribute-sort' // Check directive attribute order +// import remarkLintDirectiveCollapsedAttribute from 'remark-lint-directive-collapsed-attribute' // Check that collapsed attributes are used in directives +// import remarkLintDirectiveQuoteStyle from 'remark-lint-directive-quote-style' // Check quotes of directive attributes +// import remarkLintDirectiveShortcutAttribute from 'remark-lint-directive-shortcut-attribute' // Check that shortcut attributes are used in directives +// import remarkLintDirectiveUniqueAttributeName from 'remark-lint-directive-unique-attribute-name' // Check that attribute names are unique +import remarkLintFencedCodeFlag from 'remark-lint-fenced-code-flag'; // Warn when fenced code blocks occur without language flag +// import remarkLintFileExtension from 'remark-lint-file-extension' // (Crashes with "Cannot use 'in' operator to search for 'start' in undefined") Warn when the file’s extension violates the given style +import remarkLintFinalDefinition from 'remark-lint-final-definition'; // Warn when definitions are not placed at the end of the file +import remarkLintFirstHeadingLevel from 'remark-lint-first-heading-level'; // Warn when the first heading has a level other than a specified value +import remarkLintHeadingIncrement from 'remark-lint-heading-increment'; // Warn when headings increment with more than 1 level at a time +import remarkLintLinebreakStyle from 'remark-lint-linebreak-style'; // Warn when linebreaks violate a given or detected style +import remarkLintMaximumHeadingLength from 'remark-lint-maximum-heading-length'; // Warn when headings are too long +// import remarkLintMdxJsxAttributeSort from 'remark-lint-mdx-jsx-attribute-sort' // Check mdx jsx attribute order +// import remarkLintMdxJsxNoVoidChildren from 'remark-lint-mdx-jsx-no-void-children' // Check mdx jsx quotes +// import remarkLintMdxJsxQuoteStyle from 'remark-lint-mdx-jsx-quote-style' // Check mdx jsx quotes +// import remarkLintMdxJsxSelfClose from 'remark-lint-mdx-jsx-self-close' // Check that self-closing tags are used when possible +// import remarkLintMdxJsxShorthandAttribute from 'remark-lint-mdx-jsx-shorthand-attribute' // Check that shorthand attributes are used in MDX JSX +// import remarkLintMdxJsxUniqueAttributeName from 'remark-lint-mdx-jsx-unique-attribute-name' // Check that mdx jsx attributes are unique +// import remarkLintMediaStyle from 'remark-lint-media-style' // Check whether references or resources are used +import remarkLintNoDuplicateDefinedUrls from 'remark-lint-no-duplicate-defined-urls'; // Warn on definitions that define the same urls +import remarkLintNoDuplicateDefinitions from 'remark-lint-no-duplicate-definitions'; // Warn on duplicate definitions +import remarkLintNoDuplicateHeadings from 'remark-lint-no-duplicate-headings'; // Warn on duplicate headings +import remarkLintNoDuplicateHeadingsInSection from 'remark-lint-no-duplicate-headings-in-section'; // Warn on duplicate headings in a section +// import remarkLintNoEmphasisAsHeading from 'remark-lint-no-emphasis-as-heading' // Warn when emphasis or importance is used instead of a heading +import remarkLintNoEmptyUrl from 'remark-lint-no-empty-url'; // Warn on empty URLs in links and images +import remarkLintNoFileNameArticles from 'remark-lint-no-file-name-articles'; // Warn when file name start with an article +import remarkLintNoFileNameConsecutiveDashes from 'remark-lint-no-file-name-consecutive-dashes'; // Warn when file names contain consecutive dashes +import remarkLintNoFileNameIrregularCharacters from 'remark-lint-no-file-name-irregular-characters'; // Warn when file names contain irregular characters +// import remarkLintNoFileNameMixedCase from 'remark-lint-no-file-name-mixed-case' // (Crashes with "Cannot use 'in' operator to search for 'start' in undefined") Warn when file names use mixed case +import remarkLintNoFileNameOuterDashes from 'remark-lint-no-file-name-outer-dashes'; // Warn when file names contain initial or final dashes +import remarkLintNoHeadingIndent from 'remark-lint-no-heading-indent'; // Warn when headings are indented +import remarkLintNoHeadingLikeParagraph from 'remark-lint-no-heading-like-paragraph'; // For too many hashes (h7+ “headings”) +// import remarkLintNoHeadingPunctuation from 'remark-lint-no-heading-punctuation' // Warn when headings end in illegal characters +// import remarkLintNoHiddenTableCell from 'remark-lint-no-hidden-table-cell' // Check superfluous table cells +// import remarkLintNoHtml from 'remark-lint-no-html' // Warn when HTML nodes are used +// import remarkLintNoLiteralUrls from 'remark-lint-no-literal-urls' // Warn when URLs without angle brackets are used +// import remarkLintNoMissingBlankLines from 'remark-lint-no-missing-blank-lines' // Warn when missing blank lines +import remarkLintNoMultipleToplevelHeadings from 'remark-lint-no-multiple-toplevel-headings'; // Warn when multiple top level headings are used +import remarkLintNoParagraphContentIndent from 'remark-lint-no-paragraph-content-indent'; // Warn when the content in paragraphs are indented +import remarkLintNoReferenceLikeUrl from 'remark-lint-no-reference-like-url'; // Warn when URLs are also defined identifiers +import remarkLintNoShellDollars from 'remark-lint-no-shell-dollars'; // Warn when shell code is prefixed by dollars +import remarkLintNoShortcutReferenceImage from 'remark-lint-no-shortcut-reference-image'; // Warn when shortcut reference images are used +import remarkLintNoShortcutReferenceLink from 'remark-lint-no-shortcut-reference-link'; // Warn when shortcut reference links are used +import remarkLintNoTabs from 'remark-lint-no-tabs'; // Warn when hard tabs are used instead of spaces +import remarkLintNoUndefinedReferences from 'remark-lint-no-undefined-references'; // Warn when references to undefined definitions are found +import remarkLintNoUnneededFullReferenceImage from 'remark-lint-no-unneeded-full-reference-image'; // Check that full reference images can be collapsed +import remarkLintNoUnneededFullReferenceLink from 'remark-lint-no-unneeded-full-reference-link'; // Check that full reference links can be collapsed +import remarkLintNoUnusedDefinitions from 'remark-lint-no-unused-definitions'; // Warn when unused definitions are found +import remarkLintStrikethroughMarker from 'remark-lint-strikethrough-marker'; // Warn when strikethrough markers violate the given style + +// Official rules with Prettier conflicts +// Maintained manually via https://github.com/un-ts/remark-preset-prettier?tab=readme-ov-file#disabled-remark-lint-plugins +// import remarkLintBlockquoteIndentation from 'remark-lint-blockquote-indentation' // Check whitespace after block quote markers +// import remarkLintCheckboxCharacterStyle from 'remark-lint-checkbox-character-style' // Check list item checkbox characters +// import remarkLintCodeBlockStyle from 'remark-lint-code-block-style' // Warn when code blocks do not adhere to a given style +// import remarkLintDefinitionCase from 'remark-lint-definition-case' // Warn when definition labels are not lowercase +// import remarkLintDefinitionSpacing from 'remark-lint-definition-spacing' // Warn when consecutive whitespace is used in a definition +// import remarkLintEmphasisMarker from 'remark-lint-emphasis-marker' // Warn when emphasis markers violate the given style +// import remarkLintFencedCodeMarker from 'remark-lint-fenced-code-marker' // Warn when fenced code markers violate the given style +// import remarkLintFinalNewline from 'remark-lint-final-newline' // Warn when a newline at the end of a file is missing +// import remarkLintHardBreakSpaces from 'remark-lint-hard-break-spaces' // Warn when too many spaces are used to create a hard break +// import remarkLintHeadingStyle from 'remark-lint-heading-style' // Warn when heading style violates the given style +// import remarkLintBlankLines102 from 'remark-lint-blank-lines-1-0-2' // Ensure a specific number of lines between blocks +// import remarkLintHeadingWhitespace from 'remark-lint-heading-whitespace' // Ensure heading parsing is not broken by weird whitespace +// import remarkLintLinkTitleStyle from 'remark-lint-link-title-style' // Warn when link and definition titles occur with incorrect quotes +// import remarkLintListItemBulletIndent from 'remark-lint-list-item-bullet-indent' // Warn when list item bullets are indented +// import remarkLintListItemContentIndent from 'remark-lint-list-item-content-indent' // Warn when the content of a list item has mixed indentation +// import remarkLintListItemIndent from 'remark-lint-list-item-indent' // Check the spacing between list item bullets and content +// import remarkLintListItemSpacing from 'remark-lint-list-item-spacing' // Warn when list looseness is incorrect +// import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length' // Warn when lines are too long +// import remarkLintNoBlockquoteWithoutMarker from 'remark-lint-no-blockquote-without-marker' // Warn when block quotes have blank lines without markers +// import remarkLintNoConsecutiveBlankLines from 'remark-lint-no-consecutive-blank-lines' // Warn for too many consecutive blank lines +// import remarkLintNoHeadingContentIndent from 'remark-lint-no-heading-content-indent' // Warn when heading content is indented +// import remarkLintNoTableIndentation from 'remark-lint-no-table-indentation' // Warn when tables are indented +// import remarkLintOrderedListMarkerStyle from 'remark-lint-ordered-list-marker-style' // Warn when the markers of ordered lists violate a given style +// import remarkLintOrderedListMarkerValue from 'remark-lint-ordered-list-marker-value' // Check the marker value of ordered lists +// import remarkLintRuleStyle from 'remark-lint-rule-style' // Warn when horizontal rules violate a given style +// import remarkLintStrongMarker from 'remark-lint-strong-marker' // Warn when importance (strong) markers violate the given style +// import remarkLintTableCellPadding from 'remark-lint-table-cell-padding' // Warn when table cells are incorrectly padded +// import remarkLintTablePipeAlignment from 'remark-lint-table-pipe-alignment' // Warn when table pipes are not aligned +// import remarkLintTablePipes from 'remark-lint-table-pipes' // Warn when table rows are not fenced with pipes +// import remarkLintUnorderedListMarkerStyle from 'remark-lint-unordered-list-marker-style' // Warn when markers of unordered lists violate a given style + +// Community maintained rules +// import remarkLintAlphabetizeLists from 'remark-lint-alphabetize-lists' // Ensure list items are in alphabetical order +// import remarkLintAppropriateHeading from 'remark-lint-appropriate-heading' // Check that the top level heading matches the directory name +// import remarkLintAreLinksValid from 'remark-lint-are-links-valid' // Check if your links are reachable and/or unique +// import remarkLintCheckToc from 'remark-lint-check-toc' // Ensure TOC is correct +// import remarkLintCode from 'remark-lint-code' // Lint fenced code blocks by corresponding language tags, currently supporting ESLint +// import remarkLintCodeBlockSplitList from 'remark-lint-code-block-split-list' // Ensure code block inside list doesn't split the list +// import remarkLintDoubleLink from 'remark-lint-double-link' // Ensure the same URL is not linked multiple times. +// import remarkLintEmojiLimit from 'remark-lint-emoji-limit' // Enforce a limit of emoji per paragraph +// import remarkLintFencedCodeFlagCase from 'remark-lint-fenced-code-flag-case' // Warn when fenced code blocks have improperly cased language flags +// import remarkLintFrontmatterSchema from 'remark-lint-frontmatter-schema' // Validate YAML frontmatter against a JSON schema +// import remarkLintHeadingCapitalization from 'remark-lint-heading-capitalization' // Ensure headings capitalization is correct +// import remarkLintHeadingLength from 'remark-lint-heading-length' // Ensure headings have the appropriate length +// import remarkLintHeadingWordLength from 'remark-lint-heading-word-length' // Warn when headings have too many or too few words with unicode support +// import remarkLintListItemStyle from 'remark-lint-list-item-style' // Warn when list items violate a given capitalization or punctuation style +// import remarkLintMatchPunctuation from 'remark-lint-match-punctuation' // Ensures punctuations are used in pairs if necessary. +// import remarkLintMdashStyle from 'remark-lint-mdash-style' // Ensure em-dash (—) style follows a standard format +// import remarkLintNoChinesePunctuationInNumber from 'remark-lint-no-chinese-punctuation-in-number' // Ensures that Chinese punctuation’s not used in numbers +// import remarkLintNoDeadUrls from 'remark-lint-no-dead-urls' // Check that external links are alive +// import remarkLintNoEmptySections from 'remark-lint-no-empty-sections' // Ensure every heading is followed by content (forming a section) +// import remarkLintNoRepeatPunctuation from 'remark-lint-no-repeat-punctuation' // Ensures punctuation is not repeated +// import remarkLintNoUrlTrailingSlash from 'remark-lint-no-url-trailing-slash' // Ensure that the href of links has no trailing slash +// import remarkLintWriteGood from 'remark-lint-write-good' // Wrapper for write-good + +// Community maintained rules with Prettier conflicts +// Maintained manually via https://github.com/un-ts/remark-preset-prettier?tab=readme-ov-file#disabled-remark-lint-plugins +// import remarkLintBooksLinks from 'remark-lint-books-links' // Ensure links in lists of books follow a standard format +// import remarkLintNoLongCode from 'remark-lint-no-long-code' // Ensures that each line in code block won't be too long. +// import remarkLintSpacesAroundNumber from 'remark-lint-spaces-around-number' // Ensures there are spaces around number and Chinese. +// import remarkLintSpacesAroundWord from 'remark-lint-spaces-around-word' // Ensures there are spaces around English word and Chinese. + +const remarkSharedConfig: RemarkConfig = { + plugins: [ + remarkLint, + remarkFrontmatter, + remarkGfm, + remarkDirective, + remarkLintCheckboxContentIndent, + [remarkLintFencedCodeFlag, { allowEmpty: false }], + remarkLintFinalDefinition, + remarkLintFirstHeadingLevel, + remarkLintHeadingIncrement, + remarkLintLinebreakStyle, + remarkLintMaximumHeadingLength, + remarkLintNoDuplicateDefinedUrls, + remarkLintNoDuplicateDefinitions, + remarkLintNoDuplicateHeadings, + remarkLintNoDuplicateHeadingsInSection, + remarkLintNoEmptyUrl, + remarkLintNoFileNameArticles, + remarkLintNoFileNameConsecutiveDashes, + remarkLintNoFileNameIrregularCharacters, + remarkLintNoFileNameOuterDashes, + remarkLintNoHeadingIndent, + remarkLintNoHeadingLikeParagraph, + remarkLintNoMultipleToplevelHeadings, + remarkLintNoParagraphContentIndent, + remarkLintNoReferenceLikeUrl, + remarkLintNoShellDollars, + remarkLintNoShortcutReferenceImage, + remarkLintNoShortcutReferenceLink, + remarkLintNoTabs, + [ + remarkLintNoUndefinedReferences, + { + allow: [ + '…', + '...', + // GitHub Alerts / Admonitions + // https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts + // See also the custom text handler below in settings + '!NOTE', + '!TIP', + '!IMPORTANT', + '!WARNING', + '!CAUTION', + ], + }, + ], + remarkLintNoUnneededFullReferenceImage, + remarkLintNoUnneededFullReferenceLink, + remarkLintNoUnusedDefinitions, + remarkLintNoUnusedDefinitions, + remarkLintStrikethroughMarker, + remarkValidateLinks, + ], + // Prettier will enforce some of these? + settings: { + bullet: '-', + emphasis: '_', + handlers: { + // Prevent escaping GFM alerts / admonitions + // https://github.com/Xunnamius/symbiote/blob/main/src/assets/transformers/_.remarkrc.mjs.ts + // This is necessary in addition to the remark-lint-no-undefined-references rule customization below. + text(node: Text, parent: Parents | undefined, state: State, info: Info) { + // Call the default text handler, then strip the leading "\" from GFM alerts + // Case insensitivity is important! + const markdownString = mdastToTextHandlers.text(node, parent, state, info); + return markdownString.replace(/^\\(?=\[!(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION)\])/i, ''); + }, + }, + rule: '-', + strong: '*', + }, +}; + +/** + * Overrides specific rules in a set of plugins. + * + * This function searches through an array of plugins to find and override + * multiple plugins by their names, replacing their arguments with new ones. + * + * See this link for why we need this: + * https://github.com/remarkjs/remark-lint/issues/165 + * + */ +function overrideRules( + plugins: PluggableList | undefined, + rules: Array<[string, unknown]>, +): PluggableList { + plugins ??= []; + + for (let [ruleName, newArguments] of rules) { + // Internally, function names are different from the package names + ruleName = ruleName.replace(/^remark-lint-/, 'remark-lint:'); + + let ruleFunction: unknown; + const index = plugins.findIndex((plugin) => { + if (Array.isArray(plugin)) { + if (plugin[0].name === ruleName) { + ruleFunction = plugin[0]; + return true; + } + } else if ('name' in plugin && plugin.name === ruleName) { + ruleFunction = plugin; + return true; + } + + return false; + }); + + if (index !== -1) { + plugins.splice(index, 1, [ruleFunction, newArguments] as Pluggable); + } + } + + return plugins; +} + +/** + * **Remark Shared Configuration** + * @see [@envsa/remark-config](https://github.com/envsa/shared-config/tree/main/packages/remark-config) + * @see [@envsa/shared-config](https://github.com/envsa/shared-config) + * @example + * ```js + * export default remarkConfig({ + * rules: [ + * ['remark-lint-first-heading-level', 2], + * ['remarkValidateLinks', { repository: false }], + * ], + * }) + * ``` + */ +export function remarkConfig(options?: { + plugins?: PluggableList | undefined; + rules?: Array<[string, unknown]>; + settings?: RemarkConfig['settings']; +}): RemarkConfig { + const { + plugins = [], + rules = [], + settings, + } = options ?? { + plugins: undefined, + rules: undefined, + settings: undefined, + }; + return { + ...remarkSharedConfig, + plugins: overrideRules([...(remarkSharedConfig.plugins ?? []), ...plugins], rules), + settings: { ...remarkSharedConfig.settings, ...settings }, + }; +} + +export default remarkSharedConfig; diff --git a/packages/remark-config/tsconfig.json b/packages/remark-config/tsconfig.json new file mode 100644 index 0000000..3bad3a7 --- /dev/null +++ b/packages/remark-config/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "allowImportingTsExtensions": false, + "declaration": true, + "noEmit": false, + "outDir": "dist" + }, + "include": ["./src/index.ts"] +} diff --git a/packages/repo-config/init/.npmrc b/packages/repo-config/init/.npmrc index f74c8b1..4df60bb 100644 --- a/packages/repo-config/init/.npmrc +++ b/packages/repo-config/init/.npmrc @@ -10,4 +10,5 @@ public-hoist-pattern[]=*eslint* public-hoist-pattern[]=*knip* public-hoist-pattern[]=*mdat* public-hoist-pattern[]=*prettier* +public-hoist-pattern[]=*remark* public-hoist-pattern[]=*stylelint* diff --git a/packages/repo-config/readme.md b/packages/repo-config/readme.md index 0ef76b7..438eebb 100644 --- a/packages/repo-config/readme.md +++ b/packages/repo-config/readme.md @@ -37,7 +37,7 @@ In order to work around some hoisting issues related to plugin resolution in the -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > diff --git a/packages/shared-config/readme.md b/packages/shared-config/readme.md index e5593d7..e91d8e2 100644 --- a/packages/shared-config/readme.md +++ b/packages/shared-config/readme.md @@ -56,6 +56,7 @@ It takes care of dependencies, configuration, invocation, and reporting for the - [Knip](https://knip.dev/) - [VS Code](https://code.visualstudio.com) (extension recommendations, extension settings and useful snippets) - [mdat](https://github.com/kitschpatrol/mdat) (markdown templating and expansion tool) +- [remarklint](https://github.com/remarkjs/remark-lint) - [browserslist](https://browsersl.ist/) for unified browser support across projects - Minimal repo boilerplate (`.npmrc`, `.gitignore`, etc.) @@ -75,11 +76,12 @@ This particular readme is for the [`@envsa/shared-config`](https://www.npmjs.com - [`@envsa/knip-config`](https://github.com/envsa/shared-config/blob/main/packages/knip-config/readme.md) (`envsa-knip` command) - [`@envsa/mdat-config`](https://github.com/envsa/shared-config/blob/main/packages/mdat-config/readme.md) (`envsa-mdat` command) - [`@envsa/prettier-config`](https://github.com/envsa/shared-config/blob/main/packages/prettier-config/readme.md) (`envsa-prettier` command) +- [`@envsa/remark-config`](https://github.com/envsa/shared-config/blob/main/packages/remark-config/readme.md) (`envsa-remark` command) - [`@envsa/repo-config`](https://github.com/envsa/shared-config/blob/main/packages/repo-config/readme.md) (`envsa-repo` command) - [`@envsa/stylelint-config`](https://github.com/envsa/shared-config/blob/main/packages/stylelint-config/readme.md) (`envsa-stylelint` command) - [`@envsa/typescript-config`](https://github.com/envsa/shared-config/blob/main/packages/typescript-config/readme.md) (`envsa-typescript` command) -> \[!IMPORTANT] +> [!IMPORTANT] > > Any of these packages may be installed and run on their own via CLI if desired. However, in general, the idea is to use `@envsa/shared-config` to easily run them all simultaneously over a repo with a single command with options to either check or (where possible) fix problems, with output aggregated into a single report. @@ -103,6 +105,7 @@ envsa-eslint init envsa-stylelint init envsa-cspell init envsa-knip init +envsa-remark init envsa-prettier init envsa-browserslist init ``` @@ -307,7 +310,7 @@ envsa print-config [file] -Recall that the `@kitschpatrol/shared-config` package aggregates integration and invocation of the other tool-specific packages in this monorepo. Running a cli command on `kpi` effectively runs the same command against all the tool-specific packages. +Recall that the `@envsa/shared-config` package aggregates integration and invocation of the other tool-specific packages in this monorepo. Running a cli command on `envsa` effectively runs the same command against all the tool-specific packages. ## Implementation notes @@ -327,7 +330,7 @@ The monorepo must be kept intact, as the sub-packages depend on scripts in the p The pnpm authors consider module hoisting harmful, and I tend to agree, but certain exceptions are carved out as necessary and accommodated via the `.npmrc` file included in `@envsa/repo-config`: -- CSpell, mdat, ESLint, and Prettier all need to be hoisted via `public-hoist-pattern` to be accessible in `pnpm exec` scripts and to VS Code plugins. +- CSpell, remark, mdat, ESLint, and Prettier all need to be hoisted via `public-hoist-pattern` to be accessible in `pnpm exec` scripts and to VS Code plugins. - Even basic file-only packages like `repo-config` seem to need to be hoisted via for their bin scripts to be accessible via `pnpm exec` diff --git a/packages/shared-config/src/command.ts b/packages/shared-config/src/command.ts index 0f53857..fd44a89 100644 --- a/packages/shared-config/src/command.ts +++ b/packages/shared-config/src/command.ts @@ -12,6 +12,7 @@ import { commandDefinition as eslintCommand } from '../../eslint-config/src/comm import { commandDefinition as knipCommand } from '../../knip-config/src/command.js'; import { commandDefinition as mdatCommand } from '../../mdat-config/src/command.js'; import { commandDefinition as prettierCommand } from '../../prettier-config/src/command.js'; +import { commandDefinition as remarkCommand } from '../../remark-config/src/command.js'; import { commandDefinition as repoCommand } from '../../repo-config/src/command.js'; import { commandDefinition as stylelintCommand } from '../../stylelint-config/src/command.js'; import { commandDefinition as typescriptCommand } from '../../typescript-config/src/command.js'; @@ -22,6 +23,7 @@ const subcommandDefinitions = [ knipCommand, mdatCommand, prettierCommand, + remarkCommand, repoCommand, stylelintCommand, typescriptCommand, diff --git a/packages/stylelint-config/readme.md b/packages/stylelint-config/readme.md index 2499836..20611d6 100644 --- a/packages/stylelint-config/readme.md +++ b/packages/stylelint-config/readme.md @@ -25,7 +25,7 @@ It's a shared [Stylelint](https://stylelint.io) config, plus a command-line tool -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > @@ -52,7 +52,7 @@ To use just this Stylelint config in isolation: 3. Add the starter `stylelint.config.js` file to your project root, and add any customizations you'd like: ```sh - pnpm exec kpi-stylelint init + pnpm exec envsa-stylelint init ``` ## Rules diff --git a/packages/typescript-config/readme.md b/packages/typescript-config/readme.md index 8534674..e09db1f 100644 --- a/packages/typescript-config/readme.md +++ b/packages/typescript-config/readme.md @@ -25,7 +25,7 @@ It's a shared [TypeScript](https://www.typescriptlang.org/) `tsconfig.json` conf -> \[!IMPORTANT] +> [!IMPORTANT] > > **You can use this package on its own, but it's recommended to use [`@envsa/shared-config`](https://www.npmjs.com/package/@envsa/shared-config) instead for a single-dependency and single-package approach to linting and fixing your project.** > @@ -35,7 +35,7 @@ It's a shared [TypeScript](https://www.typescriptlang.org/) `tsconfig.json` conf ## Setup -> \[!NOTE] +> [!NOTE] > > The package treats `typescript` as a peer dependency - it expects you to have `typescript` installed in your project. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dae3e5c..1769746 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@envsa/prettier-config': specifier: workspace:* version: link:packages/prettier-config + '@envsa/remark-config': + specifier: workspace:* + version: link:packages/remark-config '@envsa/repo-config': specifier: workspace:* version: link:packages/repo-config @@ -367,6 +370,144 @@ importers: specifier: ^2.14.0 version: 2.14.0 + packages/remark-config: + dependencies: + '@pinojs/json-colorizer': + specifier: ^4.0.0 + version: 4.0.0 + '@types/mdast': + specifier: ^4.0.4 + version: 4.0.4 + cosmiconfig: + specifier: ^9.0.0 + version: 9.0.0(typescript@5.7.3) + execa: + specifier: ^9.5.2 + version: 9.5.2 + find-workspaces: + specifier: ^0.3.1 + version: 0.3.1 + fs-extra: + specifier: ^11.3.0 + version: 11.3.0 + mdast-util-to-markdown: + specifier: ^2.1.2 + version: 2.1.2 + prettier: + specifier: ^3.5.0 + version: 3.5.1 + remark-directive: + specifier: ^3.0.1 + version: 3.0.1 + remark-frontmatter: + specifier: ^5.0.0 + version: 5.0.0 + remark-gfm: + specifier: ^4.0.0 + version: 4.0.1 + remark-lint: + specifier: ^10.0.1 + version: 10.0.1 + remark-lint-checkbox-content-indent: + specifier: ^5.0.1 + version: 5.0.1 + remark-lint-fenced-code-flag: + specifier: ^4.1.1 + version: 4.1.1 + remark-lint-final-definition: + specifier: ^4.0.2 + version: 4.0.2 + remark-lint-first-heading-level: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-heading-increment: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-linebreak-style: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-maximum-heading-length: + specifier: ^4.1.1 + version: 4.1.1 + remark-lint-no-duplicate-defined-urls: + specifier: ^3.0.1 + version: 3.0.1 + remark-lint-no-duplicate-definitions: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-duplicate-headings: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-duplicate-headings-in-section: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-empty-url: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-file-name-articles: + specifier: ^3.0.1 + version: 3.0.1 + remark-lint-no-file-name-consecutive-dashes: + specifier: ^3.0.1 + version: 3.0.1 + remark-lint-no-file-name-irregular-characters: + specifier: ^3.0.1 + version: 3.0.1 + remark-lint-no-file-name-outer-dashes: + specifier: ^3.0.1 + version: 3.0.1 + remark-lint-no-heading-indent: + specifier: ^5.0.1 + version: 5.0.1 + remark-lint-no-heading-like-paragraph: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-multiple-toplevel-headings: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-paragraph-content-indent: + specifier: ^5.0.1 + version: 5.0.1 + remark-lint-no-reference-like-url: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-shell-dollars: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-shortcut-reference-image: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-shortcut-reference-link: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-tabs: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-undefined-references: + specifier: ^5.0.1 + version: 5.0.1 + remark-lint-no-unneeded-full-reference-image: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-unneeded-full-reference-link: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-no-unused-definitions: + specifier: ^4.0.1 + version: 4.0.1 + remark-lint-strikethrough-marker: + specifier: ^3.0.1 + version: 3.0.1 + remark-stringify: + specifier: ^11.0.0 + version: 11.0.0 + remark-validate-links: + specifier: ^13.0.2 + version: 13.1.0 + unified: + specifier: ^11.0.5 + version: 11.0.5 + packages/repo-config: dependencies: '@pinojs/json-colorizer': @@ -1427,6 +1568,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/hosted-git-info@3.0.5': + resolution: {integrity: sha512-Dmngh7U003cOHPhKGyA7LWqrnvcTyILNgNPmNCxlx7j8MIi54iBliiT8XqVLIQ3GchoOjVAyBzNJVyuaJjqokg==} + '@types/is-empty@1.2.3': resolution: {integrity: sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==} @@ -1519,6 +1663,9 @@ packages: resolution: {integrity: sha512-EwVHlp5l+2vp8CoqJm9KikPZgi3gbdZAtabKT9KPShGeOcJhsv4Zdo3oc8T8I0uKEmYoU4ItyxbptjF08enaxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@vitest/eslint-plugin@1.1.31': resolution: {integrity: sha512-xlsLr+e+AXZ/00eVZCtNmMeCJoJaRCoLDiAgLcxgQjSS1EertieB2MUHf8xIqPKs9lECc/UpL+y1xDcpvi02hw==} peerDependencies: @@ -1876,6 +2023,9 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2228,6 +2378,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} @@ -2498,6 +2652,9 @@ packages: fastq@1.19.0: resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + fd-package-json@1.2.0: resolution: {integrity: sha512-45LSPmWf+gC5tdCQMNH4s9Sr00bIkiD9aN7dc5hqkrEw1geRYyDQS1v1oMHAW3ysfxfndqGsrDREHHjNNbKUfA==} @@ -2568,6 +2725,10 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -2634,6 +2795,9 @@ packages: git-hooks-list@3.2.0: resolution: {integrity: sha512-ZHG9a1gEhUMX1TvGrLdyWb9kDopCBbTnI8z4JgRMYxsijWipgjSEYoPWqBuIB0DnRnvqlQSEeVmzpeuPm7NdFQ==} + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2980,6 +3144,10 @@ packages: known-css-properties@0.35.0: resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} + levenshtein-edit-distance@1.0.0: + resolution: {integrity: sha512-gpgBvPn7IFIAL32f0o6Nsh2g+5uOvkt4eK9epTfgE4YVxBxwVhJ/p1888lMm/u8mXdu1ETLSi6zeEmkBI+0F3w==} + hasBin: true + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3052,6 +3220,9 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -3059,12 +3230,42 @@ packages: mathml-tag-names@2.1.3: resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + mdast-comment-marker@3.0.0: + resolution: {integrity: sha512-bt08sLmTNg00/UtVDiqZKocxqvQqqyQZAg1uaRuO/4ysXV5motg7RolF5o5yy/sY1rG0v2XgZEqFWho1+2UquA==} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + mdast-util-from-markdown@0.8.5: resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} mdast-util-from-markdown@2.0.2: resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + mdast-util-mdx-expression@2.0.1: resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} @@ -3080,6 +3281,9 @@ packages: mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdast-util-to-markdown@2.1.2: resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} @@ -3119,6 +3323,33 @@ packages: micromark-core-commonmark@2.0.2: resolution: {integrity: sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==} + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-mdx-expression@3.0.0: resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} @@ -3701,6 +3932,9 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + propose@0.0.5: + resolution: {integrity: sha512-Jary1vb+ap2DIwOGfyiadcK4x1Iu3pzpkDBy8tljFPmQvnc9ES3m1PMZOMiWOG50cfoAyYNtGeBzrp+Rlh4G9A==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -3735,6 +3969,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quotation@2.0.3: + resolution: {integrity: sha512-yEc24TEgCFLXx7D4JHJJkK4JFVtatO8fziwUxY4nB/Jbea9o9CVS3gt22mA0W7rPYAGW2fWzYDSOtD94PwOyqA==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -3781,6 +4018,108 @@ packages: resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} hasBin: true + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-lint-checkbox-content-indent@5.0.1: + resolution: {integrity: sha512-R1gV4vGkgJQZQFIGve1paj4mVDUWlgX0KAHhjNpSyzuwuSIDoxWpEuSJSxcnczESgcjM4yVrZqEGMYi/fqZK0w==} + + remark-lint-fenced-code-flag@4.1.1: + resolution: {integrity: sha512-hKPqowc79jrJL47AfnqDThvE8Q249nHCleR5nxuf9ybriMqcAHYxragKzU5c4W1fNy20bTfFdZz/iAAQAk9kwg==} + + remark-lint-final-definition@4.0.2: + resolution: {integrity: sha512-fz3UAcFQef77Zb8rz4za2R6y7pdyJot22iGtFoNIKdtbcNa8IKKEVoY3NIfrsLfhrjwzcha1Sp3fFA9NF6lc4w==} + + remark-lint-first-heading-level@4.0.1: + resolution: {integrity: sha512-ZqH476wQU2rk3L2X1Ef/FsdDZJsSkMqTkEjKyeac/hxnwDZ8ZLYYMmm4UKTgVZTtqFUkNYzgGEPAFXtrppHbJA==} + + remark-lint-heading-increment@4.0.1: + resolution: {integrity: sha512-uat7RTQn0hGlMv62p7yjLlg3tO3RljFbH6C+0M+5BNEF+s3NrA8jJgqW0UwLLNdCd3EABCKaWloHumT57ND7PQ==} + + remark-lint-linebreak-style@4.0.1: + resolution: {integrity: sha512-RplUkmfPbTzqYgJMtsjq/ZBM6mjBC0JoXpzmlLtlWE70iE7qgMc37IwYdV3R9ebdYE0iE/knmtd+XFTS70XTEg==} + + remark-lint-maximum-heading-length@4.1.1: + resolution: {integrity: sha512-99yonukJ+e0uhx0zGH4uq6H9mhO7FA1ufmuToODH1N+X3ja61Grvlvvlq9UbP9+gbfbWgN97QGKPaTlE29FpaQ==} + + remark-lint-no-duplicate-defined-urls@3.0.1: + resolution: {integrity: sha512-NRIznPGHA7Run0PWkb3aFX8b/SdAhnbUkIxGVTmuS+1c0GuFH/2QrYiSMbVAq/vGevA6FJHiKkKaiUprc5QHug==} + + remark-lint-no-duplicate-definitions@4.0.1: + resolution: {integrity: sha512-Ek+A/xDkv5Nn+BXCFmf+uOrFSajCHj6CjhsHjtROgVUeEPj726yYekDBoDRA0Y3+z+U30AsJoHgf/9Jj1IFSug==} + + remark-lint-no-duplicate-headings-in-section@4.0.1: + resolution: {integrity: sha512-gGt+tepkW/XyU1tRyYuhNKjljSnRPEoy8vM2MKRHX+l48mPm6oLPA0EA4QAfk6yKHf7rM1sfKjPQwhzEectuEA==} + + remark-lint-no-duplicate-headings@4.0.1: + resolution: {integrity: sha512-6lggqnpIe5FepikjYF2me3ovKV4oD/rAz8WmwVbLR2cLkce1iH+PB7jyxk/A2gQQqrDcIlRMA5Ct2Yj56cEwhQ==} + + remark-lint-no-empty-url@4.0.1: + resolution: {integrity: sha512-FSQIO+Q63kNNSUfbvvWPz6ES4q1gJIc4aMjohch9bfKwcv6wWZc6UkjlMMi823I124p6onrY/F8KKECv06H5YQ==} + + remark-lint-no-file-name-articles@3.0.1: + resolution: {integrity: sha512-h31ZDDJV2T6g9WLBrXg1CJ1m8M170O/tlDPAEPGCa/rxwKvMcfum4yicaot0ZKbUZ1uEPjVSUPDeo3sU0zciCQ==} + + remark-lint-no-file-name-consecutive-dashes@3.0.1: + resolution: {integrity: sha512-qGJRZ81sowEjv1dBodbHZ29pDZbrFpxiQQ6gBvkkHkkoYPekdnr8iUxmV38HcqH8+JNW1O4ELr+m71AA9/34Mw==} + + remark-lint-no-file-name-irregular-characters@3.0.1: + resolution: {integrity: sha512-kNm16eDnPqbN05W0RLIedHi40YzHf1esPHbNKv12AljKWptdCTS72uGjAbqUSZ48dRoKtJzL0HJ0OAqXIWUyxA==} + + remark-lint-no-file-name-outer-dashes@3.0.1: + resolution: {integrity: sha512-QIMrBPZKZ6BwQRPM65HhEHcJv6+wZnZ4z2ikvx2ht40cSmIN7ZTL7wKKJlnpF+4Ioi9XUj+cRHWqEhwJ9LCQIw==} + + remark-lint-no-heading-indent@5.0.1: + resolution: {integrity: sha512-R/KkR9Qfh0AM3asadSnQQXMHu6BNZxPbxLI9h9JBPIZM+EtzycDlhaAHbOlQUdaHA5UEANhYENZBLrueH50Cdg==} + + remark-lint-no-heading-like-paragraph@4.0.1: + resolution: {integrity: sha512-1sscTjv/F/mK5cNThz6fu57xcLgLdB0rl9vJ3BEwh7U4V5cIKp1tdFQhaguweSBnKCjCVaiU7HsEdle01Ai07Q==} + + remark-lint-no-multiple-toplevel-headings@4.0.1: + resolution: {integrity: sha512-8sepobIOu3PlDOuMH7jtri+LH4tFNVQU+aqKSkrlNRdp831fYz9S+jA2crTVqWqxVbTwiF96uJWePv8/9qmHnA==} + + remark-lint-no-paragraph-content-indent@5.0.1: + resolution: {integrity: sha512-qOEUd+63vZlAiRxiJpThpPIzJkimo5H9n34iY2tZnN/+5SkM6MNEeKyy798inA9JMgjA/l8cCVa80y4CXYNriQ==} + + remark-lint-no-reference-like-url@4.0.1: + resolution: {integrity: sha512-GXS73779bPnJSqvCfOK2XzGzCWL5ggyk53KE049oOYTS55vmc26PjeW+ykbGfXIazRazZ1DLGaAqNoU9jCnZ4w==} + + remark-lint-no-shell-dollars@4.0.1: + resolution: {integrity: sha512-UPE1DNCIkLtnS3YFD065Gkq5lQqfndBDpX8Ct/Zjn7M0/hzCyf9B6tpwCU0I20m9jzhS/CSY6mxYnAiEg+KkFA==} + + remark-lint-no-shortcut-reference-image@4.0.1: + resolution: {integrity: sha512-hQhJ3Dr8ZWRdj7qm6+9vcPpqtGchhENA2UHOmcTraLf6dN1cFATCgY/HbTbRIN6NkG/EEClTgRC1QCokWR2Mmw==} + + remark-lint-no-shortcut-reference-link@4.0.1: + resolution: {integrity: sha512-YxciuUZc90QaJYhayGO80lS3zxEOBgwwLW1MKYB7AfUdkrLcLVlS+DFloiq0MZ7EDVXuuGUEnIzyjyLSbI5BUA==} + + remark-lint-no-tabs@4.0.1: + resolution: {integrity: sha512-+lhGUgY3jhTwWn1x+tTIJNy5Fbs2NcYXCobRY7xeszY0VKPCBF2GyELafOVnr+iTmosXLuhZPp5YwNezQKH9IQ==} + + remark-lint-no-undefined-references@5.0.1: + resolution: {integrity: sha512-j3qOk+jry1NPNbUmydGJpfbo1LeuZkvXOwr8ocxh1ymDzHf2GMCiToAiicDNaOuG85RkiIzLvnnCV5I7Mo5q8w==} + + remark-lint-no-unneeded-full-reference-image@4.0.1: + resolution: {integrity: sha512-SbtaHQ+Ra8pHn71bAFPVQvhiBaVsk4uj44DYB4H/82+RrndInCE/UD7hcxNqGPxNu6vGa7njSRIatXohNQpP4A==} + + remark-lint-no-unneeded-full-reference-link@4.0.1: + resolution: {integrity: sha512-NDPJH3PNAZiJai+JzAFPUJzHNAPmPZncTMApknzg2vZffa3ED5sXMKP9aGOe7z4GaBlalUwtlOlz2Zgu9wzV3w==} + + remark-lint-no-unused-definitions@4.0.1: + resolution: {integrity: sha512-AdMbaCeMpj32HvDUuyI+bQyu/405Nby/rgFW8XDpI7U7ufPhHl+jj9J4NgeW7Z8DrODGr0iFgPNt6JtNLskFdA==} + + remark-lint-strikethrough-marker@3.0.1: + resolution: {integrity: sha512-b4ABvTmqhtQKZqoiNQdz/jPfUyYnRv3Rs47XWp27t5C5aejD+Ct7MiMqegQmmVWBg4Bn+CGq2D7ldXJ3eJNTpA==} + + remark-lint@10.0.1: + resolution: {integrity: sha512-1+PYGFziOg4pH7DDf1uMd4AR3YuO2EMnds/SdIWMPGT7CAfDRSnAmpxPsJD0Ds3IKpn97h3d5KPGf1WFOg6hXQ==} + remark-mdat@0.7.5: resolution: {integrity: sha512-Q+XnJH+EXGNIXMAaXz0YDBZ842fWixCmD8ptQty4wCkDZ5X013ahnAqhj2C+p86PvStFv0Fgdr98yTs/O+DTOA==} engines: {node: ^18.19.0 || >=20.5.0, pnpm: '>=9.0.0'} @@ -3788,12 +4127,18 @@ packages: remark-mdx@3.1.0: resolution: {integrity: sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==} + remark-message-control@8.0.0: + resolution: {integrity: sha512-brpzOO+jdyE/mLqvqqvbogmhGxKygjpCUCG/PwSCU43+JZQ+RM+sSzkCWBcYvgF3KIAVNIoPsvXjBkzO7EdsYQ==} + remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remark-validate-links@13.1.0: + resolution: {integrity: sha512-z+glZ4zoRyrWimQHtoqJEFJdPoIR1R1SDr/JoWjmS6EsYlyhxNuCHtIt165gmV7ltOSFJ+rGsipqRGfBPInd7A==} + repeat-string@1.6.1: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} @@ -3953,6 +4298,9 @@ packages: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} @@ -4170,6 +4518,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} @@ -4275,6 +4626,12 @@ packages: unified-engine@11.2.2: resolution: {integrity: sha512-15g/gWE7qQl9tQ3nAEbMd5h9HV1EACtFs6N9xaRBZICoCwnNGbal1kOs++ICf4aiTdItZxU2s/kYWhW7htlqJg==} + unified-lint-rule@3.0.1: + resolution: {integrity: sha512-HxIeQOmwL19DGsxHXbeyzKHBsoSCFO7UtRVUvT2v61ptw/G+GbysWcrpHdfs5jqbIFDA11MoKngIhQK0BeTVjA==} + + unified-message-control@5.0.0: + resolution: {integrity: sha512-B2cSAkpuMVVmPP90KCfKdBhm1e9KYJ+zK3x5BCa0N65zpq1Ybkc9C77+M5qwR8FWO7RF3LM5QRRPZtgjW6DUCw==} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -4287,6 +4644,9 @@ packages: unist-util-position-from-estree@2.0.0: resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + unist-util-stringify-position@2.0.3: resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} @@ -4343,6 +4703,9 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} @@ -5341,6 +5704,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/hosted-git-info@3.0.5': {} + '@types/is-empty@1.2.3': {} '@types/json-schema@7.0.15': {} @@ -5463,6 +5828,8 @@ snapshots: '@typescript-eslint/types': 8.24.1 eslint-visitor-keys: 4.2.0 + '@ungap/structured-clone@1.3.0': {} + '@vitest/eslint-plugin@1.1.31(@typescript-eslint/utils@8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3)(vitest@3.0.6(@types/debug@4.1.12)(@types/node@22.13.4)(jiti@2.4.2)(tsx@4.19.3)(yaml@2.7.0))': dependencies: '@typescript-eslint/utils': 8.24.1(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3) @@ -5824,6 +6191,8 @@ snapshots: clsx@2.1.1: {} + collapse-white-space@2.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -6209,6 +6578,8 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + escodegen@2.1.0: dependencies: esprima: 4.0.1 @@ -6623,6 +6994,10 @@ snapshots: dependencies: reusify: 1.0.4 + fault@2.0.1: + dependencies: + format: 0.2.2 + fd-package-json@1.2.0: dependencies: walk-up-path: 3.0.1 @@ -6708,6 +7083,8 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + format@0.2.2: {} + forwarded@0.2.0: {} fresh@0.5.2: {} @@ -6785,6 +7162,8 @@ snapshots: git-hooks-list@3.2.0: {} + github-slugger@2.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -7101,6 +7480,8 @@ snapshots: known-css-properties@0.35.0: {} + levenshtein-edit-distance@1.0.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -7160,10 +7541,40 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + markdown-table@3.0.4: {} + math-intrinsics@1.1.0: {} mathml-tag-names@2.1.3: {} + mdast-comment-marker@3.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-mdx-expression: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + mdast-util-from-markdown@0.8.5: dependencies: '@types/mdast': 3.0.15 @@ -7191,6 +7602,74 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + mdast-util-mdx-expression@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 @@ -7245,6 +7724,18 @@ snapshots: '@types/mdast': 4.0.4 unist-util-is: 6.0.0 + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + mdast-util-to-markdown@2.1.2: dependencies: '@types/mdast': 4.0.4 @@ -7320,6 +7811,81 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.1 + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.2 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.1 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.1 + micromark-extension-mdx-expression@3.0.0: dependencies: '@types/estree': 1.0.6 @@ -7926,6 +8492,10 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + propose@0.0.5: + dependencies: + levenshtein-edit-distance: 1.0.0 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -7988,6 +8558,8 @@ snapshots: queue-microtask@1.2.3: {} + quotation@2.0.3: {} + range-parser@1.2.1: {} raw-body@2.5.2: @@ -8044,6 +8616,298 @@ snapshots: dependencies: jsesc: 0.5.0 + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-lint-checkbox-content-indent@5.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-phrasing: 4.1.0 + pluralize: 8.0.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + + remark-lint-fenced-code-flag@4.1.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-phrasing: 4.1.0 + quotation: 2.0.3 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + + remark-lint-final-definition@4.0.2: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-mdx: 3.0.0 + mdast-util-phrasing: 4.1.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + remark-lint-first-heading-level@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-mdx: 3.0.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + transitivePeerDependencies: + - supports-color + + remark-lint-heading-increment@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-mdx: 3.0.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + remark-lint-linebreak-style@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + unified-lint-rule: 3.0.1 + vfile-location: 5.0.3 + vfile-message: 4.0.2 + + remark-lint-maximum-heading-length@4.1.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + transitivePeerDependencies: + - supports-color + + remark-lint-no-duplicate-defined-urls@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-phrasing: 4.1.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + + remark-lint-no-duplicate-definitions@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-phrasing: 4.1.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + + remark-lint-no-duplicate-headings-in-section@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + remark-lint-no-duplicate-headings@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + remark-lint-no-empty-url@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-file-name-articles@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + + remark-lint-no-file-name-consecutive-dashes@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + + remark-lint-no-file-name-irregular-characters@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + + remark-lint-no-file-name-outer-dashes@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + + remark-lint-no-heading-indent@5.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-phrasing: 4.1.0 + pluralize: 8.0.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-heading-like-paragraph@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-phrasing: 4.1.0 + pluralize: 8.0.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-multiple-toplevel-headings@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-mdx: 3.0.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + + remark-lint-no-paragraph-content-indent@5.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-phrasing: 4.1.0 + pluralize: 8.0.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile-location: 5.0.3 + + remark-lint-no-reference-like-url@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + + remark-lint-no-shell-dollars@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + collapse-white-space: 2.1.0 + mdast-util-phrasing: 4.1.0 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-shortcut-reference-image@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-shortcut-reference-link@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-tabs@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + vfile-location: 5.0.3 + + remark-lint-no-undefined-references@5.0.1: + dependencies: + '@types/mdast': 4.0.4 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + micromark-util-normalize-identifier: 2.0.1 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile-location: 5.0.3 + + remark-lint-no-unneeded-full-reference-image@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + micromark-util-normalize-identifier: 2.0.1 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-unneeded-full-reference-link@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + micromark-util-normalize-identifier: 2.0.1 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + + remark-lint-no-unused-definitions@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + unified-lint-rule: 3.0.1 + unist-util-visit: 5.0.0 + + remark-lint-strikethrough-marker@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + unified-lint-rule: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile-message: 4.0.2 + + remark-lint@10.0.1: + dependencies: + '@types/mdast': 4.0.4 + remark-message-control: 8.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + remark-mdat@0.7.5: dependencies: '@types/mdast': 4.0.4 @@ -8061,6 +8925,15 @@ snapshots: transitivePeerDependencies: - supports-color + remark-message-control@8.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-comment-marker: 3.0.0 + unified-message-control: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.4 @@ -8076,6 +8949,23 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + remark-validate-links@13.1.0: + dependencies: + '@types/hosted-git-info': 3.0.5 + '@types/mdast': 4.0.4 + github-slugger: 2.0.0 + hosted-git-info: 7.0.2 + mdast-util-to-hast: 13.2.0 + mdast-util-to-string: 4.0.0 + propose: 0.0.5 + trough: 2.2.0 + unified-engine: 11.2.2 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - bluebird + - supports-color + repeat-string@1.6.1: {} require-directory@2.1.1: {} @@ -8261,6 +9151,8 @@ snapshots: dependencies: whatwg-url: 7.1.0 + space-separated-tokens@2.0.2: {} + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 @@ -8541,6 +9433,8 @@ snapshots: tree-kill@1.2.2: {} + trim-lines@3.0.1: {} + trough@2.2.0: {} ts-api-utils@2.0.1(typescript@5.7.3): @@ -8657,6 +9551,24 @@ snapshots: - bluebird - supports-color + unified-lint-rule@3.0.1: + dependencies: + '@types/unist': 3.0.3 + trough: 2.2.0 + unified: 11.0.5 + vfile: 6.0.3 + + unified-message-control@5.0.0: + dependencies: + '@types/unist': 3.0.3 + devlop: 1.1.0 + space-separated-tokens: 2.0.2 + unist-util-is: 6.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + vfile-message: 4.0.2 + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -8679,6 +9591,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position@2.0.3: dependencies: '@types/unist': 2.0.11 @@ -8734,6 +9650,11 @@ snapshots: vary@1.1.2: {} + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + vfile-message@4.0.2: dependencies: '@types/unist': 3.0.3 diff --git a/readme.md b/readme.md index e5593d7..e91d8e2 100644 --- a/readme.md +++ b/readme.md @@ -56,6 +56,7 @@ It takes care of dependencies, configuration, invocation, and reporting for the - [Knip](https://knip.dev/) - [VS Code](https://code.visualstudio.com) (extension recommendations, extension settings and useful snippets) - [mdat](https://github.com/kitschpatrol/mdat) (markdown templating and expansion tool) +- [remarklint](https://github.com/remarkjs/remark-lint) - [browserslist](https://browsersl.ist/) for unified browser support across projects - Minimal repo boilerplate (`.npmrc`, `.gitignore`, etc.) @@ -75,11 +76,12 @@ This particular readme is for the [`@envsa/shared-config`](https://www.npmjs.com - [`@envsa/knip-config`](https://github.com/envsa/shared-config/blob/main/packages/knip-config/readme.md) (`envsa-knip` command) - [`@envsa/mdat-config`](https://github.com/envsa/shared-config/blob/main/packages/mdat-config/readme.md) (`envsa-mdat` command) - [`@envsa/prettier-config`](https://github.com/envsa/shared-config/blob/main/packages/prettier-config/readme.md) (`envsa-prettier` command) +- [`@envsa/remark-config`](https://github.com/envsa/shared-config/blob/main/packages/remark-config/readme.md) (`envsa-remark` command) - [`@envsa/repo-config`](https://github.com/envsa/shared-config/blob/main/packages/repo-config/readme.md) (`envsa-repo` command) - [`@envsa/stylelint-config`](https://github.com/envsa/shared-config/blob/main/packages/stylelint-config/readme.md) (`envsa-stylelint` command) - [`@envsa/typescript-config`](https://github.com/envsa/shared-config/blob/main/packages/typescript-config/readme.md) (`envsa-typescript` command) -> \[!IMPORTANT] +> [!IMPORTANT] > > Any of these packages may be installed and run on their own via CLI if desired. However, in general, the idea is to use `@envsa/shared-config` to easily run them all simultaneously over a repo with a single command with options to either check or (where possible) fix problems, with output aggregated into a single report. @@ -103,6 +105,7 @@ envsa-eslint init envsa-stylelint init envsa-cspell init envsa-knip init +envsa-remark init envsa-prettier init envsa-browserslist init ``` @@ -307,7 +310,7 @@ envsa print-config [file] -Recall that the `@kitschpatrol/shared-config` package aggregates integration and invocation of the other tool-specific packages in this monorepo. Running a cli command on `kpi` effectively runs the same command against all the tool-specific packages. +Recall that the `@envsa/shared-config` package aggregates integration and invocation of the other tool-specific packages in this monorepo. Running a cli command on `envsa` effectively runs the same command against all the tool-specific packages. ## Implementation notes @@ -327,7 +330,7 @@ The monorepo must be kept intact, as the sub-packages depend on scripts in the p The pnpm authors consider module hoisting harmful, and I tend to agree, but certain exceptions are carved out as necessary and accommodated via the `.npmrc` file included in `@envsa/repo-config`: -- CSpell, mdat, ESLint, and Prettier all need to be hoisted via `public-hoist-pattern` to be accessible in `pnpm exec` scripts and to VS Code plugins. +- CSpell, remark, mdat, ESLint, and Prettier all need to be hoisted via `public-hoist-pattern` to be accessible in `pnpm exec` scripts and to VS Code plugins. - Even basic file-only packages like `repo-config` seem to need to be hoisted via for their bin scripts to be accessible via `pnpm exec` diff --git a/src/path-utils.ts b/src/path-utils.ts index f7907b5..3ef7fbf 100644 --- a/src/path-utils.ts +++ b/src/path-utils.ts @@ -20,6 +20,7 @@ function isDirectoryBelow(directory: string, parent: string): boolean { * '/Users/lrella/Code/shared-config/packages/knip-config', * '/Users/lrella/Code/shared-config/packages/mdat-config', * '/Users/lrella/Code/shared-config/packages/prettier-config', + * '/Users/lrella/Code/shared-config/packages/remark-config', * '/Users/lrella/Code/shared-config/packages/repo-config', * '/Users/lrella/Code/shared-config/packages/shared-config', * '/Users/lrella/Code/shared-config/packages/stylelint-config',