diff --git a/docs/framework/react/basic-setup.md b/docs/framework/react/basic-setup.md index 5fff9f98..aa24ec9d 100644 --- a/docs/framework/react/basic-setup.md +++ b/docs/framework/react/basic-setup.md @@ -74,6 +74,6 @@ createRoot(document.getElementById('root')!).render( ) ``` -Finally add any additional configuration you desire to the `TanStackDevtools` component, more information can be found under the [TanStack Devtools Configuration](../../../configuration.md) section. +Finally add any additional configuration you desire to the `TanStackDevtools` component, more information can be found under the [TanStack Devtools Configuration](../../configuration.md) section. A complete working example can be found in our [basic example](https://tanstack.com/devtools/latest/docs/framework/react/examples/basic). diff --git a/docs/framework/react/guides/custom-plugins.md b/docs/framework/react/guides/custom-plugins.md index cf792f81..a4107cf3 100644 --- a/docs/framework/react/guides/custom-plugins.md +++ b/docs/framework/react/guides/custom-plugins.md @@ -137,7 +137,7 @@ export function DevtoolPanel() { ## Application Integration -This step follows what's shown in [basic-setup](../../basic-setup.md) for a more documented guide go check it out. As well as the complete [custom-devtools example](https://tanstack.com/devtools/latest/docs/framework/react/examples/custom-devtools) in our examples section. +This step follows what's shown in [basic-setup](../basic-setup.md) for a more documented guide go check it out. As well as the complete [custom-devtools example](https://tanstack.com/devtools/latest/docs/framework/react/examples/custom-devtools) in our examples section. Main.tsx ```tsx diff --git a/docs/framework/solid/basic-setup.md b/docs/framework/solid/basic-setup.md index f497f12d..238dfedf 100644 --- a/docs/framework/solid/basic-setup.md +++ b/docs/framework/solid/basic-setup.md @@ -68,6 +68,6 @@ render(() => ( ), document.getElementById('root')!) ``` -Finally add any additional configuration you desire to the `TanStackDevtools` component, more information can be found under the [TanStack Devtools Configuration](../../../configuration.md) section. +Finally add any additional configuration you desire to the `TanStackDevtools` component, more information can be found under the [TanStack Devtools Configuration](../../configuration.md) section. A complete working example can be found in our [examples section](https://tanstack.com/devtools/latest/docs/framework/solid/examples). diff --git a/docs/installation.md b/docs/installation.md index 6ec26217..f1535529 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -44,4 +44,4 @@ npm install -D @tanstack/devtools-vite ``` -Read more about using the devtools in production in our [Production docs](https://tanstack.com/devtools/latest/docs/production). \ No newline at end of file +Read more about using the devtools in production in our [Production docs](./production.md). \ No newline at end of file diff --git a/docs/reference/classes/tanstackdevtoolscore.md b/docs/reference/classes/tanstackdevtoolscore.md index b2f3a0d8..7c93c312 100644 --- a/docs/reference/classes/tanstackdevtoolscore.md +++ b/docs/reference/classes/tanstackdevtoolscore.md @@ -23,7 +23,7 @@ Defined in: [devtools/src/core.tsx:53](https://github.com/TanStack/devtools/blob ##### init -[`TanStackDevtoolsInit`](../interfaces/tanstackdevtoolsinit.md) +[`TanStackDevtoolsInit`](./interfaces/tanstackdevtoolsinit.md) #### Returns @@ -67,7 +67,7 @@ Defined in: [devtools/src/core.tsx:94](https://github.com/TanStack/devtools/blob ##### config -`Partial`\<[`TanStackDevtoolsInit`](../interfaces/tanstackdevtoolsinit.md)\> +`Partial`\<[`TanStackDevtoolsInit`](./interfaces/tanstackdevtoolsinit.md)\> #### Returns diff --git a/eslint.config.js b/eslint.config.js index 427a7579..8071cbe8 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,7 +1,7 @@ // @ts-check // @ts-ignore Needed due to moduleResolution Node vs Bundler -import { tanstackConfig } from '@tanstack/config/eslint' +import { tanstackConfig } from '@tanstack/eslint-config' import unusedImports from 'eslint-plugin-unused-imports' export default [ diff --git a/nx.json b/nx.json index b3b2c519..daed29c4 100644 --- a/nx.json +++ b/nx.json @@ -49,6 +49,10 @@ "inputs": ["production", "^production"], "outputs": ["{projectRoot}/build", "{projectRoot}/dist"] }, + "test:docs": { + "cache": true, + "inputs": ["{workspaceRoot}/docs/**/*"] + }, "test:knip": { "cache": true, "inputs": ["{workspaceRoot}/**/*"] diff --git a/package.json b/package.json index c74510b7..9155550d 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "clean:node_modules": "find . -name 'node_modules' -type d -prune -exec rm -rf {} +", "clean:all": "pnpm run clean && pnpm run clean:node_modules", "dev": "pnpm run watch", - "docs:generate": "node scripts/generateDocs.ts", "format": "pnpm run prettier:write", + "generate-docs": "node scripts/generate-docs.ts", "lint:fix": "nx affected --target=lint:fix --exclude=examples/**", "lint:fix:all": "pnpm run format && nx run-many --targets=lint --fix", "preinstall": "node -e \"if(process.env.CI == 'true') {console.log('Skipping preinstall...'); process.exit(1)}\" || npx -y only-allow pnpm", @@ -29,6 +29,7 @@ "test": "pnpm run test:ci", "test:build": "nx affected --target=test:build --exclude=examples/**", "test:ci": "nx run-many --targets=test:format,test:eslint,test:sherif,test:knip,test:lib,test:types,test:build,build", + "test:docs": "node scripts/verify-links.ts", "test:eslint": "nx affected --target=test:eslint --exclude=examples/**", "test:format": "pnpm run prettier --check", "test:knip": "knip", @@ -41,6 +42,7 @@ }, "nx": { "includedScripts": [ + "test:docs", "test:knip", "test:sherif" ] @@ -60,13 +62,16 @@ "@faker-js/faker": "^9.9.0", "@size-limit/preset-small-lib": "^11.2.0", "@svitejs/changesets-changelog-github-compact": "^1.2.0", - "@tanstack/config": "0.20.2", + "@tanstack/eslint-config": "0.3.2", + "@tanstack/typedoc-config": "0.2.1", + "@tanstack/vite-config": "0.2.1", "@testing-library/jest-dom": "^6.8.0", "@types/node": "^22.15.2", "eslint": "^9.36.0", "eslint-plugin-unused-imports": "^4.2.0", "jsdom": "^27.0.0", "knip": "^5.64.0", + "markdown-link-extractor": "^4.0.2", "nx": "^21.5.3", "premove": "^4.0.0", "prettier": "^3.6.2", diff --git a/packages/devtools-client/vite.config.ts b/packages/devtools-client/vite.config.ts index 92e9a947..ddb68c2b 100644 --- a/packages/devtools-client/vite.config.ts +++ b/packages/devtools-client/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ diff --git a/packages/devtools-ui/vite.config.ts b/packages/devtools-ui/vite.config.ts index 7c8cb9b3..6f3f1659 100644 --- a/packages/devtools-ui/vite.config.ts +++ b/packages/devtools-ui/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import solid from 'vite-plugin-solid' import packageJson from './package.json' import type { Plugin } from 'vite' diff --git a/packages/devtools-utils/vite.config.solid.ts b/packages/devtools-utils/vite.config.solid.ts index b19485cd..c54b518f 100644 --- a/packages/devtools-utils/vite.config.solid.ts +++ b/packages/devtools-utils/vite.config.solid.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import solid from 'vite-plugin-solid' import packageJson from './package.json' import tsconfig from './tsconfig.solid.json' diff --git a/packages/devtools-utils/vite.config.ts b/packages/devtools-utils/vite.config.ts index 8a74dc1e..cf4dca44 100644 --- a/packages/devtools-utils/vite.config.ts +++ b/packages/devtools-utils/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ diff --git a/packages/devtools-vite/vite.config.ts b/packages/devtools-vite/vite.config.ts index c75b23d1..7d5bcd2f 100644 --- a/packages/devtools-vite/vite.config.ts +++ b/packages/devtools-vite/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ diff --git a/packages/devtools/vite.config.ts b/packages/devtools/vite.config.ts index 65df0745..936f78d7 100644 --- a/packages/devtools/vite.config.ts +++ b/packages/devtools/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import solid from 'vite-plugin-solid' import packageJson from './package.json' import type { Plugin } from 'vite' diff --git a/packages/event-bus-client/vite.config.ts b/packages/event-bus-client/vite.config.ts index 79dae7cd..0ee014cf 100644 --- a/packages/event-bus-client/vite.config.ts +++ b/packages/event-bus-client/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ diff --git a/packages/event-bus/vite.config.ts b/packages/event-bus/vite.config.ts index 0060a798..46a1162f 100644 --- a/packages/event-bus/vite.config.ts +++ b/packages/event-bus/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import packageJson from './package.json' const config = defineConfig({ diff --git a/packages/react-devtools/vite.config.ts b/packages/react-devtools/vite.config.ts index f6598389..37790492 100644 --- a/packages/react-devtools/vite.config.ts +++ b/packages/react-devtools/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import react from '@vitejs/plugin-react' import packageJson from './package.json' import type { Plugin } from 'vitest/config' diff --git a/packages/solid-devtools/vite.config.ts b/packages/solid-devtools/vite.config.ts index 877c177a..cb552657 100644 --- a/packages/solid-devtools/vite.config.ts +++ b/packages/solid-devtools/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import solid from 'vite-plugin-solid' import packageJson from './package.json' import type { Plugin } from 'vite' diff --git a/packages/vue-devtools/vite.config.ts b/packages/vue-devtools/vite.config.ts index dae5da82..1dca5af9 100644 --- a/packages/vue-devtools/vite.config.ts +++ b/packages/vue-devtools/vite.config.ts @@ -1,5 +1,5 @@ import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/config/vite' +import { tanstackViteConfig } from '@tanstack/vite-config' import vue from '@vitejs/plugin-vue' import packageJson from './package.json' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef097799..1fda11e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,9 +20,15 @@ importers: '@svitejs/changesets-changelog-github-compact': specifier: ^1.2.0 version: 1.2.0(encoding@0.1.13) - '@tanstack/config': - specifier: 0.20.2 - version: 0.20.2(@types/node@22.15.2)(@typescript-eslint/utils@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1))(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.6(@types/node@22.15.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.1)) + '@tanstack/eslint-config': + specifier: 0.3.2 + version: 0.3.2(@typescript-eslint/utils@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@tanstack/typedoc-config': + specifier: 0.2.1 + version: 0.2.1(typescript@5.9.3) + '@tanstack/vite-config': + specifier: 0.2.1 + version: 0.2.1(@types/node@22.15.2)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.6(@types/node@22.15.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.1)) '@testing-library/jest-dom': specifier: ^6.8.0 version: 6.9.1 @@ -41,6 +47,9 @@ importers: knip: specifier: ^5.64.0 version: 5.71.0(@types/node@22.15.2)(typescript@5.9.3) + markdown-link-extractor: + specifier: ^4.0.2 + version: 4.0.3 nx: specifier: ^21.5.3 version: 21.6.10 @@ -1041,14 +1050,6 @@ packages: resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} - '@commitlint/parse@19.8.1': - resolution: {integrity: sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==} - engines: {node: '>=v18'} - - '@commitlint/types@19.8.1': - resolution: {integrity: sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==} - engines: {node: '>=v18'} - '@csstools/color-helpers@5.1.0': resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} engines: {node: '>=18'} @@ -1917,12 +1918,6 @@ packages: '@jridgewell/trace-mapping@0.3.29': resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - '@kwsites/file-exists@1.1.1': - resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} - - '@kwsites/promise-deferred@1.1.1': - resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -2943,10 +2938,6 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 - '@tanstack/config@0.20.2': - resolution: {integrity: sha512-CWVv5kK7QdfnrAyvUo31spmqZjn+zpxKRqsyJDhGY7I4QweJeCbRJrlhzH3trv18ZyW3thRvtiHWfX1MdUr2VA==} - engines: {node: '>=18'} - '@tanstack/devtools-client@0.0.3': resolution: {integrity: sha512-kl0r6N5iIL3t9gGDRAv55VRM3UIyMKVH83esRGq7xBjYsRLe/BeCIN2HqrlJkObUXQMKhy7i8ejuGOn+bDqDBw==} engines: {node: '>=18'} @@ -3014,10 +3005,6 @@ packages: resolution: {integrity: sha512-vGY+CWsFZeac3dELgB6UZ4c7OacwsLb8hvL2gLS6hTgy8Fl0Bm/aLokHaeDIP+q9F9HUZTnp360z9uv78eg8pg==} engines: {node: '>=18'} - '@tanstack/publish-config@0.2.1': - resolution: {integrity: sha512-URVXmXwlZXL75AFyvyOORef1tv2f16dEaFntwLYnBHoKLQMxyWYRzQrnXooxO1xf+GidJuDSZSC6Rc9UX1aK7g==} - engines: {node: '>=18'} - '@tanstack/query-core@5.90.11': resolution: {integrity: sha512-f9z/nXhCgWDF4lHqgIE30jxLe4sYv15QodfdPDKYAk7nAEjNcndy4dHz3ezhdUaR23BpWa4I2EH4/DZ0//Uf8A==} @@ -3357,9 +3344,6 @@ packages: '@types/chai@5.2.2': resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} - '@types/conventional-commits-parser@5.0.1': - resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} - '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -3735,10 +3719,6 @@ packages: resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==} hasBin: true - JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -3871,9 +3851,6 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} - array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} @@ -4204,9 +4181,6 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} @@ -4233,15 +4207,6 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} - conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} - - conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} - engines: {node: '>=16'} - hasBin: true - convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -4542,10 +4507,6 @@ packages: domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} - dot-prop@9.0.0: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} @@ -5390,6 +5351,9 @@ packages: html-entities@2.3.3: resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + html-link-extractor@1.0.5: + resolution: {integrity: sha512-ADd49pudM157uWHwHQPUSX4ssMsvR/yHIswOR5CUfBdK9g9ZYGMhVSE6KZVHJ6kCkR0gH4htsfzU6zECDNVwyw==} + html-to-image@1.11.13: resolution: {integrity: sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==} @@ -5544,10 +5508,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - is-path-inside@4.0.0: resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} engines: {node: '>=12'} @@ -5581,10 +5541,6 @@ packages: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} - is-text-path@2.0.0: - resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} - engines: {node: '>=8'} - is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} @@ -5709,13 +5665,6 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - - jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - junk@4.0.1: resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} engines: {node: '>=12.20'} @@ -5957,6 +5906,14 @@ packages: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true + markdown-link-extractor@4.0.3: + resolution: {integrity: sha512-aEltJiQ4/oC0h6Jbw/uuATGSHZPkcH8DIunNH1A0e+GSFkvZ6BbBkdvBTVfIV8r6HapCU3yTd0eFdi3ZeM1eAQ==} + + marked@17.0.1: + resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==} + engines: {node: '>= 20'} + hasBin: true + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -5970,10 +5927,6 @@ packages: mdurl@2.0.0: resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} - merge-anything@5.1.7: resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} engines: {node: '>=12.13'} @@ -7032,9 +6985,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-git@3.30.0: - resolution: {integrity: sha512-q6lxyDsCmEal/MEGhP1aVyQ3oxnagGlBDOVSIB4XUVLl1iZh0Pah6ebC9V4xBap/RfgP2WlI8EKs0WS0rMEJHg==} - simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -7295,10 +7245,6 @@ packages: text-decoder@1.2.3: resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - text-extensions@2.4.0: - resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} - engines: {node: '>=8'} - text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} @@ -7313,9 +7259,6 @@ packages: resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} engines: {node: '>=18'} - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -7569,10 +7512,6 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - unixify@1.0.0: resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} engines: {node: '>=0.10.0'} @@ -8619,17 +8558,6 @@ snapshots: '@colors/colors@1.6.0': {} - '@commitlint/parse@19.8.1': - dependencies: - '@commitlint/types': 19.8.1 - conventional-changelog-angular: 7.0.0 - conventional-commits-parser: 5.0.0 - - '@commitlint/types@19.8.1': - dependencies: - '@types/conventional-commits-parser': 5.0.1 - chalk: 5.6.2 - '@csstools/color-helpers@5.1.0': {} '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': @@ -9292,14 +9220,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@kwsites/file-exists@1.1.1': - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@kwsites/promise-deferred@1.1.1': {} - '@manypkg/find-root@1.1.0': dependencies: '@babel/runtime': 7.28.4 @@ -10308,22 +10228,6 @@ snapshots: tailwindcss: 4.1.17 vite: 7.2.6(@types/node@22.15.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.1) - '@tanstack/config@0.20.2(@types/node@22.15.2)(@typescript-eslint/utils@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1))(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.6(@types/node@22.15.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.1))': - dependencies: - '@tanstack/eslint-config': 0.3.2(@typescript-eslint/utils@8.48.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) - '@tanstack/publish-config': 0.2.1 - '@tanstack/typedoc-config': 0.2.1(typescript@5.9.3) - '@tanstack/vite-config': 0.2.1(@types/node@22.15.2)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.6(@types/node@22.15.2)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.1)) - transitivePeerDependencies: - - '@types/node' - - '@typescript-eslint/utils' - - eslint - - eslint-import-resolver-node - - rollup - - supports-color - - typescript - - vite - '@tanstack/devtools-client@0.0.3': dependencies: '@tanstack/devtools-event-client': 0.3.5 @@ -10439,15 +10343,6 @@ snapshots: '@tanstack/devtools-event-client': 0.3.5 '@tanstack/store': 0.7.7 - '@tanstack/publish-config@0.2.1': - dependencies: - '@commitlint/parse': 19.8.1 - jsonfile: 6.2.0 - semver: 7.7.3 - simple-git: 3.30.0 - transitivePeerDependencies: - - supports-color - '@tanstack/query-core@5.90.11': {} '@tanstack/query-devtools@5.91.1': {} @@ -10997,10 +10892,6 @@ snapshots: dependencies: '@types/deep-eql': 4.0.2 - '@types/conventional-commits-parser@5.0.1': - dependencies: - '@types/node': 22.15.2 - '@types/deep-eql@4.0.2': {} '@types/estree@1.0.8': {} @@ -11469,11 +11360,6 @@ snapshots: dependencies: argparse: 2.0.1 - JSONStream@1.3.5: - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - abbrev@3.0.1: {} abort-controller@3.0.0: @@ -11604,8 +11490,6 @@ snapshots: aria-query@5.3.2: {} - array-ify@1.0.0: {} - array-union@2.1.0: {} assertion-error@2.0.1: {} @@ -11961,11 +11845,6 @@ snapshots: commondir@1.0.1: {} - compare-func@2.0.0: - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - compare-versions@6.1.1: {} compatx@0.2.0: {} @@ -11988,17 +11867,6 @@ snapshots: consola@3.4.2: {} - conventional-changelog-angular@7.0.0: - dependencies: - compare-func: 2.0.0 - - conventional-commits-parser@5.0.0: - dependencies: - JSONStream: 1.3.5 - is-text-path: 2.0.0 - meow: 12.1.1 - split2: 4.2.0 - convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} @@ -12253,10 +12121,6 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 - dot-prop@5.3.0: - dependencies: - is-obj: 2.0.0 - dot-prop@9.0.0: dependencies: type-fest: 4.41.0 @@ -13220,6 +13084,10 @@ snapshots: html-entities@2.3.3: {} + html-link-extractor@1.0.5: + dependencies: + cheerio: 1.1.2 + html-to-image@1.11.13: {} html-void-elements@3.0.0: {} @@ -13365,8 +13233,6 @@ snapshots: is-number@7.0.0: {} - is-obj@2.0.0: {} - is-path-inside@4.0.0: {} is-plain-obj@2.1.0: {} @@ -13391,10 +13257,6 @@ snapshots: dependencies: better-path-resolve: 1.0.0 - is-text-path@2.0.0: - dependencies: - text-extensions: 2.4.0 - is-unicode-supported@0.1.0: {} is-url-superb@4.0.0: {} @@ -13509,14 +13371,6 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.2.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonparse@1.3.1: {} - junk@4.0.1: {} jwt-decode@4.0.0: {} @@ -13756,6 +13610,13 @@ snapshots: punycode.js: 2.3.1 uc.micro: 2.1.0 + markdown-link-extractor@4.0.3: + dependencies: + html-link-extractor: 1.0.5 + marked: 17.0.1 + + marked@17.0.1: {} + math-intrinsics@1.1.0: {} mdast-util-to-hast@13.2.0: @@ -13774,8 +13635,6 @@ snapshots: mdurl@2.0.0: {} - meow@12.1.1: {} - merge-anything@5.1.7: dependencies: is-what: 4.1.16 @@ -14989,14 +14848,6 @@ snapshots: signal-exit@4.1.0: {} - simple-git@3.30.0: - dependencies: - '@kwsites/file-exists': 1.1.1 - '@kwsites/promise-deferred': 1.1.1 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 @@ -15267,8 +15118,6 @@ snapshots: dependencies: b4a: 1.6.7 - text-extensions@2.4.0: {} - text-hex@1.0.0: {} thenify-all@1.6.0: @@ -15281,8 +15130,6 @@ snapshots: throttleit@2.1.0: {} - through@2.3.8: {} - tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} @@ -15541,8 +15388,6 @@ snapshots: universalify@0.1.2: {} - universalify@2.0.1: {} - unixify@1.0.0: dependencies: normalize-path: 2.1.1 diff --git a/scripts/generateDocs.ts b/scripts/generate-docs.ts similarity index 55% rename from scripts/generateDocs.ts rename to scripts/generate-docs.ts index 7140817d..a82ebf6b 100644 --- a/scripts/generateDocs.ts +++ b/scripts/generate-docs.ts @@ -1,8 +1,6 @@ import { resolve } from 'node:path' import { fileURLToPath } from 'node:url' -import { readFileSync, writeFileSync } from 'node:fs' -import { generateReferenceDocs } from '@tanstack/config/typedoc' -import { glob } from 'tinyglobby' +import { generateReferenceDocs } from '@tanstack/typedoc-config' const __dirname = fileURLToPath(new URL('.', import.meta.url)) @@ -41,33 +39,6 @@ await generateReferenceDocs({ ], }) -// Find all markdown files matching the pattern -const markdownFiles = [ - ...(await glob('docs/reference/**/*.md')), - ...(await glob('docs/framework/*/reference/**/*.md')), -] - -console.log(`Found ${markdownFiles.length} markdown files to process\n`) - -// Process each markdown file -markdownFiles.forEach((file) => { - const content = readFileSync(file, 'utf-8') - let updatedContent = content - updatedContent = updatedContent.replaceAll(/\]\(\.\.\//gm, '](../../') - // updatedContent = content.replaceAll(/\]\(\.\//gm, '](../') - updatedContent = updatedContent.replaceAll( - /\]\((?!https?:\/\/|\/\/|\/|\.\/|\.\.\/|#)([^)]+)\)/gm, - // @ts-expect-error - (match, p1) => `](../${p1})`, - ) - - // Write the updated content back to the file - if (updatedContent !== content) { - writeFileSync(file, updatedContent, 'utf-8') - console.log(`Processed file: ${file}`) - } -}) - console.log('\n✅ All markdown files have been processed!') process.exit(0) diff --git a/scripts/verify-links.ts b/scripts/verify-links.ts new file mode 100644 index 00000000..8a1c40dd --- /dev/null +++ b/scripts/verify-links.ts @@ -0,0 +1,125 @@ +import { existsSync, readFileSync, statSync } from 'node:fs' +import { extname, resolve } from 'node:path' +import { glob } from 'tinyglobby' +// @ts-ignore Could not find a declaration file for module 'markdown-link-extractor'. +import markdownLinkExtractor from 'markdown-link-extractor' + +const errors: Array<{ + file: string + link: string + resolvedPath: string + reason: string +}> = [] + +function isRelativeLink(link: string) { + return ( + !link.startsWith('/') && + !link.startsWith('http://') && + !link.startsWith('https://') && + !link.startsWith('//') && + !link.startsWith('#') && + !link.startsWith('mailto:') + ) +} + +/** Remove any trailing .md */ +function stripExtension(p: string): string { + return p.replace(`${extname(p)}`, '') +} + +function relativeLinkExists(link: string, file: string): boolean { + // Remove hash if present + const linkWithoutHash = link.split('#')[0] + // If the link is empty after removing hash, it's not a file + if (!linkWithoutHash) return false + + // Strip the file/link extensions + const filePath = stripExtension(file) + const linkPath = stripExtension(linkWithoutHash) + + // Resolve the path relative to the markdown file's directory + // Nav up a level to simulate how links are resolved on the web + let absPath = resolve(filePath, '..', linkPath) + + // Ensure the resolved path is within /docs + const docsRoot = resolve('docs') + if (!absPath.startsWith(docsRoot)) { + errors.push({ + link, + file, + resolvedPath: absPath, + reason: 'Path outside /docs', + }) + return false + } + + // Check if this is an example path + const isExample = absPath.includes('/examples/') + + let exists = false + + if (isExample) { + // Transform /docs/framework/{framework}/examples/ to /examples/{framework}/ + absPath = absPath.replace( + /\/docs\/framework\/([^/]+)\/examples\//, + '/examples/$1/', + ) + // For examples, we want to check if the directory exists + exists = existsSync(absPath) && statSync(absPath).isDirectory() + } else { + // For non-examples, we want to check if the .md file exists + if (!absPath.endsWith('.md')) { + absPath = `${absPath}.md` + } + exists = existsSync(absPath) + } + + if (!exists) { + errors.push({ + link, + file, + resolvedPath: absPath, + reason: 'Not found', + }) + } + return exists +} + +async function verifyMarkdownLinks() { + // Find all markdown files in docs directory + const markdownFiles = await glob('docs/**/*.md', { + ignore: ['**/node_modules/**'], + }) + + console.log(`Found ${markdownFiles.length} markdown files\n`) + + // Process each file + for (const file of markdownFiles) { + const content = readFileSync(file, 'utf-8') + const links: Array = markdownLinkExtractor(content) + + const relativeLinks = links.filter((link: string) => { + return isRelativeLink(link) + }) + + if (relativeLinks.length > 0) { + relativeLinks.forEach((link) => { + relativeLinkExists(link, file) + }) + } + } + + if (errors.length > 0) { + console.log(`\n❌ Found ${errors.length} broken links:`) + errors.forEach((err) => { + console.log( + `${err.file}\n link: ${err.link}\n resolved: ${err.resolvedPath}\n why: ${err.reason}\n`, + ) + }) + process.exit(1) + } else { + console.log('\n✅ No broken links found!') + } +} + +verifyMarkdownLinks().catch(console.error)