diff --git a/.gitignore b/.gitignore index 50e55cb..6eedd3f 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,6 @@ bun.lock */build/* # IntelliJ -.idea \ No newline at end of file +.idea +.eslintcache +tsconfig.tsbuildinfo \ No newline at end of file diff --git a/.remarkrc.mjs b/.remarkrc.mjs index 3a3379b..d329309 100644 --- a/.remarkrc.mjs +++ b/.remarkrc.mjs @@ -12,19 +12,22 @@ export default { remarkPresetLintRecommended, remarkNoInlineCodeFences, remarkNoHtmlLinks, - [ - remarkLintNoDeadUrls, - { - skipLocalhost: false, - skipOffline: true, - skipUrlPatterns: [ - 'https://github.com/signup', - 'https://code.visualstudio.com/', - 'https://www.conventionalcommits.org/en/v1.0.0/', - 'https://vale.sh/', - 'https://squoosh.app/', - ], // Add known flaky URL patterns here - }, - ], + // only run dead link checker in CI to save time in dev + process.env.CI + ? [ + remarkLintNoDeadUrls, + { + skipLocalhost: false, + skipOffline: true, + skipUrlPatterns: [ + 'https://github.com/signup', + 'https://code.visualstudio.com/', + 'https://www.conventionalcommits.org/en/v1.0.0/', + 'https://vale.sh/', + 'https://squoosh.app/', + ], // Add known flaky URL patterns here + }, + ] + : () => undefined, ], }; diff --git a/eslint.config.mjs b/eslint.config.mjs index 0efff8c..5d5a1e9 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,7 +1,6 @@ import js from '@eslint/js'; import astro from 'eslint-plugin-astro'; import globals from 'globals'; -import process from 'node:process'; import tseslint from 'typescript-eslint'; import { defineConfig } from 'eslint/config'; @@ -21,8 +20,7 @@ export default defineConfig([ { argsIgnorePattern: '^_' }, ], '@typescript-eslint/no-explicit-any': 'error', - // ci runs `astro check` which runs a full typescript checker - 'no-undef': process.env.CI ? 'off' : 'error', + 'no-undef': 'off', }, }, { @@ -42,8 +40,5 @@ export default defineConfig([ ImageMetadata: 'readonly', }, }, - rules: { - 'no-undef': 'off', - }, }, ]); diff --git a/package.json b/package.json index 3197978..3284349 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "prebuild": "tsx scripts/generate-glossary.ts", "predev": "tsx scripts/generate-glossary.ts", "lint": "pnpm lint:eslint && pnpm lint:md && pnpm lint:regions && pnpm lint:glossary && pnpm typecheck && pnpm vale", - "lint:eslint": "eslint .", + "lint:eslint": "eslint \"src/**/*.{ts,astro,js,mjs,css}\" \"*.mjs\" --cache", "lint:md": "remark src/content/docs --ext mdx --frail", "lint:regions": "tsx scripts/validate-regions.ts", "vale": "pnpm vale:setup && vale sync && vale src/content", @@ -40,12 +40,13 @@ "@eslint/js": "^10.0.1", "@types/estree": "^1.0.9", "@types/mdast": "^4.0.4", + "@types/node": "^26.1.2", "astro-eslint-parser": "^1.4.0", "eslint": "^10.5.0", "eslint-plugin-astro": "^1.7.0", - "mdast-util-mdx": "^3.0.0", "husky": "^9.1.7", "lint-staged": "^17.0.8", + "mdast-util-mdx": "^3.0.0", "mdast-util-mdx-jsx": "^3.2.0", "mdx2vast": "^0.3.1", "prettier": "^3.8.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ba09bc..d063804 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,13 +13,13 @@ importers: version: 7.2.1 '@astrojs/starlight': specifier: ^0.41.4 - version: 0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3) + version: 0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3) '@mdi/js': specifier: ^7.4.47 version: 7.4.47 astro: specifier: ^7.1.3 - version: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) + version: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) sharp: specifier: ^0.34.5 version: 0.34.5 @@ -39,6 +39,9 @@ importers: '@types/mdast': specifier: ^4.0.4 version: 4.0.4 + '@types/node': + specifier: ^26.1.2 + version: 26.1.2 astro-eslint-parser: specifier: ^1.4.0 version: 1.4.0 @@ -92,7 +95,7 @@ importers: version: 7.0.1 starlight-links-validator: specifier: ^0.20.0 - version: 0.20.1(@astrojs/starlight@0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3))(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)) + version: 0.20.1(@astrojs/starlight@0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3))(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)) tsx: specifier: ^4.22.4 version: 4.22.4 @@ -1158,6 +1161,9 @@ packages: '@types/node@24.12.4': resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} + '@types/node@26.1.2': + resolution: {integrity: sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==} + '@types/picomatch@4.0.3': resolution: {integrity: sha512-iG0T6+nYJ9FAPmx9SsUlnwcq1ZVRuCXcVEvWnntoPlrOpwtSTKNDC9uVAxTsC3PUvJ+99n4RpAcNgBbHX3JSnQ==} @@ -3511,6 +3517,9 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + undici@8.9.0: resolution: {integrity: sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==} engines: {node: '>=22.19.0'} @@ -4078,13 +4087,13 @@ snapshots: hast-util-from-html: 2.0.3 satteri: 0.9.5 - '@astrojs/mdx@7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))': + '@astrojs/mdx@7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: '@astrojs/internal-helpers': 0.10.1 '@astrojs/markdown-remark': 7.2.1 '@mdx-js/mdx': 3.1.1 acorn: 8.16.0 - astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) + astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) es-module-lexer: 2.1.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -4110,17 +4119,17 @@ snapshots: stream-replace-string: 2.0.0 zod: 4.4.3 - '@astrojs/starlight@0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3)': + '@astrojs/starlight@0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3)': dependencies: '@astrojs/markdown-satteri': 0.3.4 - '@astrojs/mdx': 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)) + '@astrojs/mdx': 7.0.3(@astrojs/markdown-satteri@0.3.4)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)) '@astrojs/sitemap': 3.7.2 '@pagefind/default-ui': 1.4.0 '@types/hast': 3.0.4 '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 - astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) - astro-expressive-code: 0.44.1(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)) + astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) + astro-expressive-code: 0.44.1(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)) bcp-47: 2.1.0 hast-util-from-html: 2.0.3 hast-util-select: 6.0.4 @@ -4881,7 +4890,7 @@ snapshots: '@types/concat-stream@2.0.3': dependencies: - '@types/node': 24.12.4 + '@types/node': 26.1.2 '@types/debug@4.1.12': dependencies: @@ -4940,11 +4949,15 @@ snapshots: dependencies: undici-types: 7.16.0 + '@types/node@26.1.2': + dependencies: + undici-types: 8.3.0 + '@types/picomatch@4.0.3': {} '@types/sax@1.2.7': dependencies: - '@types/node': 24.12.4 + '@types/node': 26.1.2 '@types/supports-color@8.1.3': {} @@ -5178,13 +5191,13 @@ snapshots: transitivePeerDependencies: - supports-color - astro-expressive-code@0.44.1(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)): + astro-expressive-code@0.44.1(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)): dependencies: - astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) + astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) rehype-expressive-code: 0.44.1 url-extras: 0.1.0 - astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0): + astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: '@astrojs/compiler-rs': 0.3.1(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) '@astrojs/internal-helpers': 0.10.1 @@ -5234,8 +5247,8 @@ snapshots: ultrahtml: 1.6.0 unifont: 0.7.4 unstorage: 1.17.5 - vite: 8.1.5(@types/node@24.12.4)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0) - vitefu: 1.1.2(vite@8.1.5(@types/node@24.12.4)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)) + vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0) + vitefu: 1.1.2(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)) xxhash-wasm: 1.1.0 yargs-parser: 22.0.0 zod: 4.4.3 @@ -8165,11 +8178,11 @@ snapshots: spdx-license-ids@3.0.23: {} - starlight-links-validator@0.20.1(@astrojs/starlight@0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3))(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)): + starlight-links-validator@0.20.1(@astrojs/starlight@0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3))(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0)): dependencies: - '@astrojs/starlight': 0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3) + '@astrojs/starlight': 0.41.4(@astrojs/markdown-remark@7.2.1)(astro@7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0))(typescript@6.0.3) '@types/picomatch': 4.0.3 - astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@24.12.4)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) + astro: 7.1.3(@astrojs/markdown-remark@7.2.1)(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@types/node@26.1.2)(rollup@4.59.0)(tsx@4.22.4)(yaml@2.9.0) github-slugger: 2.0.0 hast-util-from-html: 2.0.3 hast-util-has-property: 3.0.0 @@ -8363,6 +8376,8 @@ snapshots: undici-types@7.16.0: {} + undici-types@8.3.0: {} + undici@8.9.0: {} unified-args@11.0.1: @@ -8620,7 +8635,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@8.1.5(@types/node@24.12.4)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0): + vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -8628,15 +8643,15 @@ snapshots: rolldown: 1.1.5 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 26.1.2 esbuild: 0.28.1 fsevents: 2.3.3 tsx: 4.22.4 yaml: 2.9.0 - vitefu@1.1.2(vite@8.1.5(@types/node@24.12.4)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)): + vitefu@1.1.2(vite@8.1.5(@types/node@26.1.2)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0)): optionalDependencies: - vite: 8.1.5(@types/node@24.12.4)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0) + vite: 8.1.5(@types/node@26.1.2)(esbuild@0.28.1)(tsx@4.22.4)(yaml@2.9.0) volar-service-css@0.0.70(@volar/language-service@2.4.28): dependencies: diff --git a/scripts/validate-regions.ts b/scripts/validate-regions.ts index d1128d0..1df61e0 100644 --- a/scripts/validate-regions.ts +++ b/scripts/validate-regions.ts @@ -1,10 +1,11 @@ import { readFileSync, readdirSync } from 'fs'; -import { join, relative } from 'path'; +import { basename, join, relative } from 'path'; import { fileURLToPath } from 'url'; const ROOT = fileURLToPath(new URL('..', import.meta.url)); const EXAMPLES_DIR = join(ROOT, 'examples'); const DOCS_DIR = join(ROOT, 'src', 'content', 'docs'); +const SKIP_DIRS = new Set(['build', '.gradle', 'node_modules', 'gradle']); const START_RE = /^\s*(?:\/\/|#|--|)?\s*\[(\w+)\]\s*$/; const END_RE = /^\s*(?:\/\/|#|--|)?\s*\[\/(\w+)\]\s*$/; @@ -15,6 +16,7 @@ const CODE_REGION_SOURCES_KEY_RE = /^codeRegionSources:\s*$/; const CODE_REGION_SOURCE_ENTRY_RE = /^\s+([\w-]+):\s*(.+?)\s*$/; const errors: string[] = []; +const extensions: Set = new Set(); function parseCodeRegionSources(content: string): Map { const sources = new Map(); @@ -35,9 +37,9 @@ function parseCodeRegionSources(content: string): Map { const m = line.match(CODE_REGION_SOURCE_ENTRY_RE); if (m) { sources.set(m[1]!, m[2]!); + extensions.add(m[2]!.split('.').at(-1)!); } } - return sources; } @@ -147,11 +149,18 @@ function validateSource(filePath: string) { } function walkExamples(dir: string) { + if (SKIP_DIRS.has(basename(dir))) { + return; + } for (const entry of readdirSync(dir, { withFileTypes: true })) { const full = join(dir, entry.name); if (entry.isDirectory()) { walkExamples(full); } else { + if (!extensions.has(full.split('.').at(-1)!)) { + // we only care about source files + continue; + } validateSource(full); } } diff --git a/tsconfig.json b/tsconfig.json index bb51518..29d2c72 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,9 +3,11 @@ "include": [".astro/types.d.ts", "**/*"], "exclude": ["dist"], "compilerOptions": { + "lib": ["DOM", "ESNext"], "paths": { "@components/*": ["./src/components/*"] }, - "checkJs": true + "checkJs": true, + "incremental": true } }