From d12dbb26cf82f67922d07dadb7d248511093826d Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 16:03:44 +0100 Subject: [PATCH 1/9] Created a script that checks for borken links --- lychee.toml | 8 +- package.json | 3 +- .../send-raw-transaction-conditional.mdx | 4 +- .../assets/deploy-superchain-erc20.mdx | 2 +- pages/stack/interop/explainer.mdx | 2 +- utils/redirects.ts | 135 ++++++++++++++++++ 6 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 utils/redirects.ts diff --git a/lychee.toml b/lychee.toml index 60e8be5a2..9ecd097e5 100644 --- a/lychee.toml +++ b/lychee.toml @@ -13,6 +13,9 @@ remap = [ "file:///(.*?)/pages/img/(.*) file:///$1/public/img/$2", "file:///(.*?)/pages/resources/(.*) file:///$1/public/resources/$2", "file:///([^#.?]+)(#.*)?$ file:///$1.mdx$2", + "file:///([^#]+)#.*$ file:///$1.mdx", + "/([^#]+)#.*$ file:///pages/$1.mdx", + "^/([^#]+)$ file:///pages/$1.mdx", "\\\\& &" ] @@ -27,6 +30,9 @@ exclude_loopback = true # Exclude all mail addresses from checking. exclude_mail = true +# Exclude all external links except ethereum-optimism GitHub +exclude_links = ['http[s]?://(?!github\.com/ethereum-optimism).*'] + # Exclude RPC URLs from checking. exclude = [ 'https://mainnet.optimism.io', @@ -41,4 +47,4 @@ exclude = [ ] # Accept these status codes -accept = ["100..=103", "200..=299", "403..=403", "502..=502"] +accept = ["100..=103", "200..=299", "403..=403", "502..=502"] \ No newline at end of file diff --git a/package.json b/package.json index b1690e4f0..08b2b6dc1 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,13 @@ "version": "0.0.1", "description": "Optimism Docs", "scripts": { - "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint && pnpm check-breadcrumbs", + "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint && pnpm check-breadcrumbs && pnpm check-redirects", "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm check-breadcrumbs", "spellcheck:lint": "cspell lint \"**/*.mdx\"", "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", "linkcheck": "lychee --config ./lychee.toml --quiet \"./pages\"", "breadcrumbs":"npx ts-node --skip-project utils/create-breadcrumbs.ts", + "check-redirects": "npx ts-node --skip-project utils/redirects.ts", "check-breadcrumbs":"npx ts-node --skip-project utils/breadcrumbs.ts", "index:docs": "npx ts-node --skip-project utils/algolia-indexer.ts", "dev": "next dev", diff --git a/pages/stack/features/send-raw-transaction-conditional.mdx b/pages/stack/features/send-raw-transaction-conditional.mdx index 5717ae5e8..75cb7e8c5 100644 --- a/pages/stack/features/send-raw-transaction-conditional.mdx +++ b/pages/stack/features/send-raw-transaction-conditional.mdx @@ -56,8 +56,8 @@ Successful submission does **NOT** guarantee inclusion! The caller must observe This feature can be enabled with the addition of a flag to op-geth. * `--rollup.sequencertxconditionalenabled` (default: false) a boolean flag which enables the rpc. -* `--rollup.sequencertxconditionalcostratelimit` (default: 5000) an integer flag that sets the rate limit for cost observable per second. +* `--rollup.sequencertxconditionalcostratelimit` (default: 5000) an integer flag that sets the rate limit for cost observable per second. - It is not advised to publicly expose this sequencer endpoint due to DoS concerns. This supplemental proxy, [op-txproxy](/stack/operators/features/op-txproxy), should be used to apply additional constraints on this endpoint prior to passing through to the sequencer. + It is not advised to publicly expose this sequencer endpoint due to DoS concerns. This supplemental proxy, [op-txproxy](/builders/chain-operators/tools/op-txproxy), should be used to apply additional constraints on this endpoint prior to passing through to the sequencer. diff --git a/pages/stack/interop/assets/deploy-superchain-erc20.mdx b/pages/stack/interop/assets/deploy-superchain-erc20.mdx index af506e238..19b1917aa 100644 --- a/pages/stack/interop/assets/deploy-superchain-erc20.mdx +++ b/pages/stack/interop/assets/deploy-superchain-erc20.mdx @@ -13,7 +13,7 @@ import { Steps } from 'nextra/components' Interop is currently in active development and not yet ready for production use. The information provided here may change. Check back regularly for the most up-to-date information. -This guide explains how to issue new assets with the `SuperchainERC20` and bridge them effectively using the `SuperchainERC20Bridge`. If you want more information about the `SuperchainERC20 standard`, see our [`SuperchainERC20` standard explainer](/stack/interop/superchain-erc20) +This guide explains how to issue new assets with the `SuperchainERC20` and bridge them effectively using the `SuperchainERC20Bridge`. If you want more information about the `SuperchainERC20 standard`, see our [`SuperchainERC20` standard explainer](/stack/interop/assets/superchain-erc20) Note that bridging assets through the Superchain using `SuperchainERC20` never affects the total supply of your asset. The supply remains fixed, and bridging only changes the chain on which your asset is located. This keeps the token's total amount the same across all networks, ensuring its value stays stable during the move and that the `SuperchainERC20` retains a unified, global supply count. diff --git a/pages/stack/interop/explainer.mdx b/pages/stack/interop/explainer.mdx index b52b28800..3f84e1b0f 100644 --- a/pages/stack/interop/explainer.mdx +++ b/pages/stack/interop/explainer.mdx @@ -24,7 +24,7 @@ Native OP Stack interoperability provides the ability to read messages and trans Superchain interop includes both the protocol layer message passing and the Superchain ERC20 token specification. * **Message passing protocol:** the initial + finalizing/executing [message](cross-chain-message) that fire events to be consumed by the chains in the [dependency set](https://specs.optimism.io/interop/dependency-set.html) -* **SuperchainERC20 token specification**: the [SuperchainERC20](superchain-erc20) turns message passing into asset transfer between chains in the interop set. Learn more about how the SuperchainERC20 token standard enables asset interoperability in the Superchain [here](/stack/interop/superchain-erc20) +* **SuperchainERC20 token specification**: the [SuperchainERC20](superchain-erc20) turns message passing into asset transfer between chains in the interop set. Learn more about how the SuperchainERC20 token standard enables asset interoperability in the Superchain [here](/stack/interop/assets/superchain-erc20) This means ETH and ERC-20s can seamlessly and securely move across L2s, and intent-based protocols (i.e., bridges) can build better experiences on top of the message passing protocol. diff --git a/utils/redirects.ts b/utils/redirects.ts new file mode 100644 index 000000000..bd2cb66b1 --- /dev/null +++ b/utils/redirects.ts @@ -0,0 +1,135 @@ +import * as fs from 'fs/promises'; +import * as path from 'path'; + +const rootDir = path.join(process.cwd(), 'pages'); +const redirectsPath = path.join(process.cwd(), 'public', '_redirects'); +const warnings: string[] = []; + +// ANSI color codes +const WHITE = '\x1b[37m'; +const GREEN = '\x1b[32m'; +const YELLOW = '\x1b[33m'; +const RESET = '\x1b[0m'; +const BOLD = '\x1b[1m'; + +interface Redirect { + from: string; + to: string; +} + +interface Summary { + total: number; + ok: number; + errors: number; +} + +function formatWarning(filePath: string, fromLink: string, toLink: string): string { + return `${WHITE}File "${filePath}" contains outdated link ${YELLOW}"${fromLink}"${WHITE} - should be updated to ${GREEN}"${toLink}"${RESET}`; +} + +async function getRedirects(): Promise { + const content = await fs.readFile(redirectsPath, 'utf-8'); + return content.split('\n') + .filter(line => line.trim() && !line.startsWith('#')) + .map(line => { + const [from, to] = line.split(/\s+/); + return { from, to }; + }); +} + +async function findMdxFiles(dir: string): Promise { + const files: string[] = []; + const entries = await fs.readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory() && !entry.name.startsWith('_')) { + files.push(...await findMdxFiles(fullPath)); + } else if (entry.isFile() && /\.(md|mdx)$/.test(entry.name)) { + files.push(fullPath); + } + } + return files; +} + +function extractLinks(content: string): string[] { + const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g; + const hrefRegex = /href="([^"]+)"/g; + const links: string[] = []; + + let match; + while ((match = markdownLinkRegex.exec(content)) !== null) { + if (!match[2].startsWith('http')) { + links.push(match[2]); + } + } + while ((match = hrefRegex.exec(content)) !== null) { + if (!match[1].startsWith('http')) { + links.push(match[1]); + } + } + return links; +} + +async function checkFile(filePath: string, redirects: Redirect[]): Promise { + const content = await fs.readFile(filePath, 'utf-8'); + const links = extractLinks(content); + const relativeFilePath = path.relative(rootDir, filePath); + + links.forEach(link => { + const redirect = redirects.find(r => r.from === link); + if (redirect) { + warnings.push(formatWarning(relativeFilePath, link, redirect.to)); + } + }); +} + +function printSummary(summary: Summary) { + console.log('\nSummary:'); + console.log(`${WHITE}Total pages 🔍 - ${summary.total}`); + console.log(`${YELLOW}Pages broken 🚫 - ${summary.errors}`); + console.log(`${GREEN}Pages OK ✅ - ${summary.ok}${RESET}`); +} + +async function main() { + const summary: Summary = { + total: 0, + ok: 0, + errors: 0 + }; + + console.log('Starting redirect link check...'); + console.log('Root directory:', rootDir); + + try { + const redirects = await getRedirects(); + const files = await findMdxFiles(rootDir); + + summary.total = files.length; + + for (const file of files) { + await checkFile(file, redirects); + } + + summary.errors = warnings.length; + summary.ok = summary.total - summary.errors; + + if (warnings.length > 0) { + console.log(`${YELLOW}${BOLD}Links that need updating:${RESET}`); + warnings.forEach(warning => console.log(warning)); + printSummary(summary); + process.exit(1); + } else { + console.log(`${GREEN}All internal links are up to date.${RESET}`); + printSummary(summary); + } + } catch (error) { + console.error(`${YELLOW}${BOLD}Error checking redirects:${RESET}`, error); + process.exit(1); + } +} + +main().catch(error => { + console.error(`${YELLOW}${BOLD}Error in main process:${RESET}`, error); + process.exit(1); +}); \ No newline at end of file From 3f525de4f531e5b54d871bcc04cf1a98c8edff4f Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 16:14:10 +0100 Subject: [PATCH 2/9] updated the link checker --- package.json | 3 +- pages/builders.mdx | 2 +- pages/builders/app-developers/overview.mdx | 6 +- .../tutorials/cross-dom-bridge-erc20.mdx | 2 +- pages/builders/chain-operators/tutorials.mdx | 2 +- pages/chain/getting-started.mdx | 2 +- pages/chain/testing/dev-node.mdx | 2 +- pages/index.mdx | 2 +- pages/stack/differences.mdx | 4 +- pages/stack/getting-started.mdx | 2 +- utils/fix-redirects.ts | 126 ++++++++++++++++++ words.txt | 9 -- 12 files changed, 140 insertions(+), 22 deletions(-) create mode 100644 utils/fix-redirects.ts diff --git a/package.json b/package.json index 08b2b6dc1..733b523eb 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,13 @@ "description": "Optimism Docs", "scripts": { "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint && pnpm check-breadcrumbs && pnpm check-redirects", - "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm check-breadcrumbs", + "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm check-breadcrumbs && pnpm fix-redirects", "spellcheck:lint": "cspell lint \"**/*.mdx\"", "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", "linkcheck": "lychee --config ./lychee.toml --quiet \"./pages\"", "breadcrumbs":"npx ts-node --skip-project utils/create-breadcrumbs.ts", "check-redirects": "npx ts-node --skip-project utils/redirects.ts", + "fix-redirects": "npx ts-node --skip-project utils/fix-redirects.ts", "check-breadcrumbs":"npx ts-node --skip-project utils/breadcrumbs.ts", "index:docs": "npx ts-node --skip-project utils/algolia-indexer.ts", "dev": "next dev", diff --git a/pages/builders.mdx b/pages/builders.mdx index ab69e59b6..98f4178cf 100644 --- a/pages/builders.mdx +++ b/pages/builders.mdx @@ -15,6 +15,6 @@ Welcome to the Builders section. Here you'll find resources and guides for devel - + diff --git a/pages/builders/app-developers/overview.mdx b/pages/builders/app-developers/overview.mdx index 21bed4d47..e38817e46 100644 --- a/pages/builders/app-developers/overview.mdx +++ b/pages/builders/app-developers/overview.mdx @@ -16,14 +16,14 @@ In this area of the Optimism Docs you'll find everything you need to know about If you're brand new to OP Mainnet, try starting with the guide on [deploying a basic contract](/chain/getting-started). It'll get you familiar with the basic steps required to get a contract deployed to the network. OP Mainnet is [EVM equivalent](https://web.archive.org/web/20231127160757/https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306) so you can feel confident that your existing Ethereum smart contract skills will carry over to OP Mainnet. -Just make sure to be aware of the few small [differences between Ethereum and OP Mainnet](/chain/differences). +Just make sure to be aware of the few small [differences between Ethereum and OP Mainnet](/stack/differences). You might also want to check out the [testing on OP Networks guide](/chain/testing/testing-apps) and the tutorial on [running a local development environment](/chain/testing/dev-node) to help you feel totally confident in your OP Mainnet deployment. - } /> + } /> - } /> + } /> } /> diff --git a/pages/builders/app-developers/tutorials/cross-dom-bridge-erc20.mdx b/pages/builders/app-developers/tutorials/cross-dom-bridge-erc20.mdx index c2de64336..883e4908c 100644 --- a/pages/builders/app-developers/tutorials/cross-dom-bridge-erc20.mdx +++ b/pages/builders/app-developers/tutorials/cross-dom-bridge-erc20.mdx @@ -31,7 +31,7 @@ Make sure to check out the [Standard Bridge guide](/builders/app-developers/brid The Optimism SDK supports any of the [Superchain networks](/chain/networks). [Some Superchain networks](https://sdk.optimism.io/enums/l2chainid) are already included in the SDK by default. -If you want to use a network that isn't included by default, you can simply [instantiate the SDK with the appropriate contract addresses](/builders/chain-operators/tutorials/sdk). +If you want to use a network that isn't included by default, you can simply [instantiate the SDK with the appropriate contract addresses](/builders/app-developers/overview). ## Dependencies diff --git a/pages/builders/chain-operators/tutorials.mdx b/pages/builders/chain-operators/tutorials.mdx index e78b0bd6b..6b2387f7a 100644 --- a/pages/builders/chain-operators/tutorials.mdx +++ b/pages/builders/chain-operators/tutorials.mdx @@ -23,5 +23,5 @@ This section provides information on adding attributes to the derivation functio - + diff --git a/pages/chain/getting-started.mdx b/pages/chain/getting-started.mdx index cf9703d44..d4af9faea 100644 --- a/pages/chain/getting-started.mdx +++ b/pages/chain/getting-started.mdx @@ -11,7 +11,7 @@ import { Steps } from 'nextra/components' This guide explains the basics of OP Mainnet development. OP Mainnet is [EVM equivalent](https://web.archive.org/web/20231127160757/https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306), meaning we run a slightly modified version of the same `geth` you run on mainnet. Therefore, the differences between OP Mainnet development and Ethereum development are minor. -But a few differences [do exist](/chain/differences). +But a few differences [do exist](/stack/differences). ## OP Mainnet and OP Sepolia endpoint URLs diff --git a/pages/chain/testing/dev-node.mdx b/pages/chain/testing/dev-node.mdx index 477176e7d..6471f9876 100644 --- a/pages/chain/testing/dev-node.mdx +++ b/pages/chain/testing/dev-node.mdx @@ -24,7 +24,7 @@ We generally recommend using the local development environment if your applicati 1. **You're building contracts on both OP Mainnet and Ethereum that need to interact with one another.** The local development environment is a great way to quickly test interactions between L1 and L2. The OP Mainnet and test networks have a communication delay between L1 and L2 that can make testing slow during the early stages of development. -2. **You're building an application that might be subject to one of the few [differences between Ethereum and OP Mainnet](/chain/differences).** Although OP Mainnet is [EVM equivalent](https://web.archive.org/web/20231127160757/https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306), it's not exactly the same as Ethereum. If you're building an application that might be subject to one of these differences, you should use the local development environment to double check that everything is running as expected. You might otherwise have unexpected issues when you move to testnet. We strongly recommend reviewing these differences carefully to see if you might fall into this category. +2. **You're building an application that might be subject to one of the few [differences between Ethereum and OP Mainnet](/stack/differences).** Although OP Mainnet is [EVM equivalent](https://web.archive.org/web/20231127160757/https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306), it's not exactly the same as Ethereum. If you're building an application that might be subject to one of these differences, you should use the local development environment to double check that everything is running as expected. You might otherwise have unexpected issues when you move to testnet. We strongly recommend reviewing these differences carefully to see if you might fall into this category. However, not everyone will need to use the local development environment. OP Mainnet is [EVM equivalent](https://web.archive.org/web/20231127160757/https://medium.com/ethereum-optimism/introducing-evm-equivalence-5c2021deb306), which means that OP Mainnet looks almost exactly like Ethereum under the hood. diff --git a/pages/index.mdx b/pages/index.mdx index 15d4aebdd..fa4175ccc 100644 --- a/pages/index.mdx +++ b/pages/index.mdx @@ -22,7 +22,7 @@ Whether you're a developer building a app on OP Mainnet, a node operator running } /> - } /> + } /> } /> diff --git a/pages/stack/differences.mdx b/pages/stack/differences.mdx index 9d6e6250c..5f370f4b0 100644 --- a/pages/stack/differences.mdx +++ b/pages/stack/differences.mdx @@ -16,11 +16,11 @@ However, there are some minor differences between the behavior of Ethereum and O ### Bridging - Deposit Transactions -Deposit transactions don't exist on L1's, and are how transactions on an L2 can be initiated from the L1. Importantly, this is how bridge applications can get L1 ETH or tokens into an L2 OP Stack chain. You can read more on deposit transactions [here](/stack/protocol/rollup/deposit-flow). +Deposit transactions don't exist on L1's, and are how transactions on an L2 can be initiated from the L1. Importantly, this is how bridge applications can get L1 ETH or tokens into an L2 OP Stack chain. You can read more on deposit transactions [here](/stack/transactions/deposit-flow). ### Bridging - Withdrawal Transactions and Fault Proofs -Withdrawal transactions are how the state of the L2 rollup can be proven to the L1. Often this involves users withdrawing tokens or ETH to the L1. Fault proofs are the mechanism by which withdrawal transactions are currently proven to the L1. You can read more about fault proofs [here](/stack/protocol/fault-proofs/explainer). +Withdrawal transactions are how the state of the L2 rollup can be proven to the L1. Often this involves users withdrawing tokens or ETH to the L1. Fault proofs are the mechanism by which withdrawal transactions are currently proven to the L1. You can read more about fault proofs [here](/stack/fault-proofs/explainer). ## Opcodes diff --git a/pages/stack/getting-started.mdx b/pages/stack/getting-started.mdx index 67096b0dc..a3f5a13a2 100644 --- a/pages/stack/getting-started.mdx +++ b/pages/stack/getting-started.mdx @@ -16,7 +16,7 @@ import { Callout } from 'nextra/components' The OP Stack consists of the many different software components managed and maintained by the Optimism Collective that, together, form the backbone of Optimism. The OP Stack is built as a public good for the Ethereum and Optimism ecosystems. -To understand how to operate an OP Stack chain, including roll-up and chain deployment basics, visit [Chain Operator guide](/builders/chain-operators/self-hosted). Check out these guides to get an overview of everything you need to know to properly support OP mainnet within your [exchange](/builders/cex-wallet-developers/cex-support) and [wallet](/builders/cex-wallet-developers/wallet-support). +To understand how to operate an OP Stack chain, including roll-up and chain deployment basics, visit [Chain Operator guide](/builders/chain-operators/self-hosted). Check out these guides to get an overview of everything you need to know to properly support OP mainnet within your [exchange](/builders/app-developers/overview) and [wallet](/builders/app-developers/overview). ## The OP Stack powers Optimism diff --git a/utils/fix-redirects.ts b/utils/fix-redirects.ts new file mode 100644 index 000000000..5d609c20b --- /dev/null +++ b/utils/fix-redirects.ts @@ -0,0 +1,126 @@ +import * as fs from 'fs/promises'; +import * as path from 'path'; + +const rootDir = path.join(process.cwd(), 'pages'); +const redirectsPath = path.join(process.cwd(), 'public', '_redirects'); +const updates: string[] = []; + +// ANSI color codes +const WHITE = '\x1b[37m'; +const GREEN = '\x1b[32m'; +const YELLOW = '\x1b[33m'; +const RESET = '\x1b[0m'; +const BOLD = '\x1b[1m'; + +interface Redirect { + from: string; + to: string; +} + +interface Summary { + total: number; + fixed: number; + skipped: number; +} + +async function getRedirects(): Promise { + const content = await fs.readFile(redirectsPath, 'utf-8'); + return content.split('\n') + .filter(line => line.trim() && !line.startsWith('#')) + .map(line => { + const [from, to] = line.split(/\s+/); + return { from, to }; + }); +} + +async function findMdxFiles(dir: string): Promise { + const files: string[] = []; + const entries = await fs.readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory() && !entry.name.startsWith('_')) { + files.push(...await findMdxFiles(fullPath)); + } else if (entry.isFile() && /\.(md|mdx)$/.test(entry.name)) { + files.push(fullPath); + } + } + return files; +} + +async function fixFile(filePath: string, redirects: Redirect[]): Promise { + let content = await fs.readFile(filePath, 'utf-8'); + let hasChanges = false; + const relativeFilePath = path.relative(rootDir, filePath); + + redirects.forEach(redirect => { + const markdownRegex = new RegExp(`\\[([^\\]]+)\\]\\(${redirect.from}\\)`, 'g'); + const hrefRegex = new RegExp(`href="${redirect.from}"`, 'g'); + + if (content.match(markdownRegex) || content.match(hrefRegex)) { + content = content + .replace(markdownRegex, `[$1](${redirect.to})`) + .replace(hrefRegex, `href="${redirect.to}"`); + + updates.push(`${WHITE}Fixed in "${relativeFilePath}": ${YELLOW}${redirect.from}${WHITE} → ${GREEN}${redirect.to}${RESET}`); + hasChanges = true; + } + }); + + if (hasChanges) { + await fs.writeFile(filePath, content); + } + + return hasChanges; +} + +function printSummary(summary: Summary) { + console.log('\nSummary:'); + console.log(`${WHITE}Total files 🔍 - ${summary.total}`); + console.log(`${GREEN}Files fixed ✅ - ${summary.fixed}`); + console.log(`${WHITE}Files skipped ⏭️ - ${summary.skipped}${RESET}`); +} + +async function main() { + const summary: Summary = { + total: 0, + fixed: 0, + skipped: 0 + }; + + console.log('Starting to fix redirect links...'); + console.log('Root directory:', rootDir); + + try { + const redirects = await getRedirects(); + const files = await findMdxFiles(rootDir); + + summary.total = files.length; + + for (const file of files) { + const wasFixed = await fixFile(file, redirects); + if (wasFixed) { + summary.fixed++; + } else { + summary.skipped++; + } + } + + if (updates.length > 0) { + console.log(`${GREEN}${BOLD}Fixed links:${RESET}`); + updates.forEach(update => console.log(update)); + printSummary(summary); + } else { + console.log(`${GREEN}No broken links found. Everything is up to date.${RESET}`); + printSummary(summary); + } + } catch (error) { + console.error(`${YELLOW}${BOLD}Error fixing redirects:${RESET}`, error); + process.exit(1); + } +} + +main().catch(error => { + console.error(`${YELLOW}${BOLD}Error in main process:${RESET}`, error); + process.exit(1); +}); \ No newline at end of file diff --git a/words.txt b/words.txt index f5ae76fbc..0efd003b6 100644 --- a/words.txt +++ b/words.txt @@ -10,7 +10,6 @@ Allnodes Allocs allocs ANDI -Ankr Apeworx Arweave authrpc @@ -150,7 +149,6 @@ holesky IERC IGNOREPRICE ignoreprice -Immunefi implicity Inator inator @@ -200,7 +198,6 @@ minsuggestedpriorityfee Mintable Mintplex MIPSEVM -Mitigations Monitorism Moralis Mordor @@ -295,8 +292,6 @@ Proxied Proxyd proxyd pseudorandomly -Pyth -Pyth's QRNG Quicknode quicknode @@ -331,9 +326,6 @@ safedb Schnorr secp SELFDESTRUCT -SEPOLIA -Sepolia -sepolia seqnr SEQUENCERHTTP sequencerhttp @@ -404,7 +396,6 @@ VMDEBUG vmdebug VMODULE vmodule -voxel Warpcast xlarge XORI From 7e72b2b43f458d3c2580c443ae069d378293f3de Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 16:32:07 +0100 Subject: [PATCH 3/9] Documented the steps involved to automate the redirect --- notes/fix-redirects.md | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 notes/fix-redirects.md diff --git a/notes/fix-redirects.md b/notes/fix-redirects.md new file mode 100644 index 000000000..206c09c83 --- /dev/null +++ b/notes/fix-redirects.md @@ -0,0 +1,83 @@ +# Redirect links management guide + +## Scripts overview +Two scripts help maintain internal links when pages are redirect: + +* `check-redirects`: Identifies links that need updating based on the `_redirects` file. +* `fix-redirects`: Automatically updates links to match `_redirects` entries. + +## Checking for broken links + +Run the check script: + +```bash +pnpm check-redirects //OR +pnpm lint +``` +## What it does + +* Scans all `.mdx` files in the docs +* Compares internal links against `_redirects` file +* Reports any outdated links that need updating +* Provides a summary of total, broken, and valid links + +## Example output + +```bash +File "builders/overview.mdx" contains outdated link "/chain/overview" - should be updated to "/stack/overview" + +Summary: +Total pages 🔍 - 50 +Pages broken 🚫 - 2 +Pages OK ✅ - 48 + +``` + +## Fixing broken links + +Fix links automatically: + +```bash +pnpm fix-redirects //OR +pnpm fix +``` + +## What it does + +* Updates all internal links to match `_redirects` entries +* Preserves other content and formatting +* Shows which files and links were updated +* Provides a summary of changes made + +## Example output + +```bash +Fixed in "builders/overview.mdx": /chain/overview → /stack/overview + +Summary: +Total files 🔍 - 50 +Files fixed ✅ - 2 +Files skipped ⏭️ - 48 +``` + +## Best practices + +1. Before running + + * Commit current changes + * Review `_redirects` file is up-to-date + * Run `check-redirects` first to preview changes + + +2. After running + + * Review git diff of updated files + * Test updated links locally + * Commit changes with descriptive message + + + +## Common issues + +* Script fails: Ensure `_redirects` file exists in public folder, it should always be there! +* No broken links found: Verify `_redirects` entries are correct. \ No newline at end of file From de92cb6588c61403cfa6b418019a970ce149f1f6 Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 16:35:50 +0100 Subject: [PATCH 4/9] revert changes made in lychee --- lychee.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/lychee.toml b/lychee.toml index 9ecd097e5..adae3d229 100644 --- a/lychee.toml +++ b/lychee.toml @@ -13,9 +13,6 @@ remap = [ "file:///(.*?)/pages/img/(.*) file:///$1/public/img/$2", "file:///(.*?)/pages/resources/(.*) file:///$1/public/resources/$2", "file:///([^#.?]+)(#.*)?$ file:///$1.mdx$2", - "file:///([^#]+)#.*$ file:///$1.mdx", - "/([^#]+)#.*$ file:///pages/$1.mdx", - "^/([^#]+)$ file:///pages/$1.mdx", "\\\\& &" ] From d69fb35470d5564c5c6000abc9be95b4b2cc9a25 Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 16:37:43 +0100 Subject: [PATCH 5/9] revert previous changes to lychee file --- lychee.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/lychee.toml b/lychee.toml index adae3d229..73b34c1e3 100644 --- a/lychee.toml +++ b/lychee.toml @@ -27,9 +27,6 @@ exclude_loopback = true # Exclude all mail addresses from checking. exclude_mail = true -# Exclude all external links except ethereum-optimism GitHub -exclude_links = ['http[s]?://(?!github\.com/ethereum-optimism).*'] - # Exclude RPC URLs from checking. exclude = [ 'https://mainnet.optimism.io', From 1d4dea4de3f0249130a26445e28d7d984c95a83e Mon Sep 17 00:00:00 2001 From: Blessing Krofegha Date: Fri, 15 Nov 2024 17:20:15 +0100 Subject: [PATCH 6/9] Update notes/fix-redirects.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- notes/fix-redirects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes/fix-redirects.md b/notes/fix-redirects.md index 206c09c83..1bcb28afe 100644 --- a/notes/fix-redirects.md +++ b/notes/fix-redirects.md @@ -1,7 +1,7 @@ # Redirect links management guide ## Scripts overview -Two scripts help maintain internal links when pages are redirect: +Two scripts help maintain internal links when pages are redirected: * `check-redirects`: Identifies links that need updating based on the `_redirects` file. * `fix-redirects`: Automatically updates links to match `_redirects` entries. From 10ecb2b0037abe449948407ce6c69478cff05e94 Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 18:22:39 +0100 Subject: [PATCH 7/9] fix lint issues --- next-env.d.ts | 2 +- words.txt | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/next-env.d.ts b/next-env.d.ts index 4f11a03dc..a4a7b3f5c 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/words.txt b/words.txt index 0efd003b6..f5ae76fbc 100644 --- a/words.txt +++ b/words.txt @@ -10,6 +10,7 @@ Allnodes Allocs allocs ANDI +Ankr Apeworx Arweave authrpc @@ -149,6 +150,7 @@ holesky IERC IGNOREPRICE ignoreprice +Immunefi implicity Inator inator @@ -198,6 +200,7 @@ minsuggestedpriorityfee Mintable Mintplex MIPSEVM +Mitigations Monitorism Moralis Mordor @@ -292,6 +295,8 @@ Proxied Proxyd proxyd pseudorandomly +Pyth +Pyth's QRNG Quicknode quicknode @@ -326,6 +331,9 @@ safedb Schnorr secp SELFDESTRUCT +SEPOLIA +Sepolia +sepolia seqnr SEQUENCERHTTP sequencerhttp @@ -396,6 +404,7 @@ VMDEBUG vmdebug VMODULE vmodule +voxel Warpcast xlarge XORI From 83db1024c059ea0b2d87deae0a7e06334a0ef63d Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 18:24:31 +0100 Subject: [PATCH 8/9] update the command --- notes/fix-redirects.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/notes/fix-redirects.md b/notes/fix-redirects.md index 1bcb28afe..fdb47fdb1 100644 --- a/notes/fix-redirects.md +++ b/notes/fix-redirects.md @@ -11,8 +11,8 @@ Two scripts help maintain internal links when pages are redirected: Run the check script: ```bash -pnpm check-redirects //OR -pnpm lint +pnpm lint //OR +pnpm check-redirects ``` ## What it does @@ -38,8 +38,8 @@ Pages OK ✅ - 48 Fix links automatically: ```bash -pnpm fix-redirects //OR -pnpm fix +pnpm fix //OR +pnpm fix-redirects ``` ## What it does From 2da87a67a0bbecaba51c65fd9f7e8a2cb9290611 Mon Sep 17 00:00:00 2001 From: krofax Date: Fri, 15 Nov 2024 18:36:30 +0100 Subject: [PATCH 9/9] revert changes --- next-env.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next-env.d.ts b/next-env.d.ts index a4a7b3f5c..4f11a03dc 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/basic-features/typescript for more information.