diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 64beee87..afd6c0cb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,6 +31,15 @@ jobs: node-version-file: ".nvmrc" cache: npm + - name: Run rumdl + uses: rvben/rumdl-action@v0 + with: + version: latest + path: "." + file_types: "md,mdx" + changed_files_only: true + fail_on_error: true + - name: Install dependencies run: npm ci diff --git a/.rumdl.toml b/.rumdl.toml new file mode 100644 index 00000000..0703b4dc --- /dev/null +++ b/.rumdl.toml @@ -0,0 +1,48 @@ +[global] +# Keep legacy long lines and preserve alignment in code examples. +disable = ["MD013", "MD034", "MD064"] + +# Enable table formatting/fixing support. +extend-enable = ["MD060"] + +# Keep this empty for now; URL auto-fixing is covered by disabled MD034. +unfixable = [] + +[MD004] +# Enforce '-' as the single bullet style across docs. +style = "dash" + +[MD046] +# Require fenced code blocks globally. +style = "fenced" + +[per-file-flavor] +# Parse MDX files with MDX-aware rules. +"**/*.mdx" = "mdx" + +[per-file-ignores] +# Historical changelog entries use legacy heading/list structures. +"src/content/changelog/*.md" = ["MD001", "MD036"] + +# README uses custom HTML header layout and no leading H1. +"README.md" = ["MD033", "MD041"] + +# Existing docs use inline HTML for embeds/widgets and should stay unchanged. +"src/content/docs/online-payments/apm/apple-pay.mdx" = ["MD033"] +"src/content/docs/online-payments/apm/google-pay.mdx" = ["MD033"] +"src/content/docs/online-payments/checkouts/card-widget.mdx" = ["MD033"] +"src/content/docs/terminal-payments/sdks/android-sdk.mdx" = ["MD033"] + +# Plugin pages use raw URL constants/props for MDX components. +"src/content/docs/online-payments/plugins/prestashop.mdx" = ["MD034"] +"src/content/docs/online-payments/plugins/woocommerce.mdx" = ["MD034"] + +# Legacy iOS SDK page has dense mixed MDX/Steps/list patterns. +# Keep it build-safe by scoping rule ignores until the page is refactored. +"src/content/docs/terminal-payments/sdks/ios-sdk.mdx" = ["MD004", "MD007", "MD012", "MD030", "MD031", "MD032", "MD040", "MD046", "MD049", "MD051", "MD060", "MD069"] + +# Legacy mixed Tabs+code snippets trigger MD046 false positives after formatting. +"src/content/docs/online-payments/guides/refund.mdx" = ["MD046", "MD051"] +"src/content/docs/online-payments/guides/single-payment.mdx" = ["MD046"] +"src/content/docs/online-payments/guides/tokenization-with-payment-sdk.mdx" = ["MD046"] +"src/content/docs/online-payments/sdks/react-native.mdx" = ["MD046"] diff --git a/AGENTS.md b/AGENTS.md index c58ee356..4aeadc31 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,6 +42,13 @@ For files in `src/content/docs/`, include frontmatter at the top of every page. CI relies on `npm run check`. When editing MDX content, preview via `npm run dev` to verify navigation, sidebar ordering, and snippet rendering. There is no Jest-style test suite; document any manual verification steps in the pull request if behavior changes or APIs are added. +## Markdown Linting Guidelines + +- Prefer fixing markdown issues in content first instead of adding linter exceptions. +- Run `npm run lint:markdown` and `npm run build` after markdown-heavy changes to catch MDX parsing regressions early. +- `rumdl` can produce impractical suggestions for complex MDX (for example mixed Tabs/Steps/components); in such cases, adding scoped ignores in `.rumdl.toml` is acceptable. +- Every new ignore must be narrowly scoped (per-file/per-rule) and include a short comment explaining why it is needed. + ## Validation Matrix Run at least the following commands before submitting changes: diff --git a/package-lock.json b/package-lock.json index 035f6e6e..f492c871 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,7 @@ "react-content-loader": "^7.1.2", "react-dom": "^19.2.4", "react-final-form": "^7.0.0", + "rumdl": "0.1.30", "sass": "^1.97.3", "starlight-image-zoom": "^0.13.0", "starlight-links-validator": "^0.19.2", @@ -5148,6 +5149,125 @@ "win32" ] }, + "node_modules/@rumdl/cli-darwin-arm64": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-darwin-arm64/-/cli-darwin-arm64-0.1.30.tgz", + "integrity": "sha512-ht15pcW+L31iDp5T/Tvl+U78kgpiZyPfFYsrvRvhot1M5+eBrt5kBaEXAXDi03tKaKK0ZdCqKQHwfpUaAuZZQA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rumdl/cli-darwin-x64": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-darwin-x64/-/cli-darwin-x64-0.1.30.tgz", + "integrity": "sha512-69hsCnEk81GiJwzcaqe8fxKMHtL+47j3criOvLjxaAtPCsfrvxkd2KSnJKj/5zElTY7pb7nL0V4Z6uy6+m00tQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rumdl/cli-linux-arm64": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-linux-arm64/-/cli-linux-arm64-0.1.30.tgz", + "integrity": "sha512-t16rv7VY0l/4MzXV29aZpnCeIsq1ZFPN9ss/C4/6EJtkBrdng6nRE5yLWFDC7G1DdyyD/IX8adp/rGKh0INQBQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rumdl/cli-linux-arm64-musl": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-linux-arm64-musl/-/cli-linux-arm64-musl-0.1.30.tgz", + "integrity": "sha512-pthBOeO7cFxtwKD7PFmfShapfqu7vlzynwOo1hFv9lYkmj0mWcMjbsfC1I0AWmPaM5kWi0Ta58K+36b9E77wNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rumdl/cli-linux-x64": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-linux-x64/-/cli-linux-x64-0.1.30.tgz", + "integrity": "sha512-tDPaWiwxOgOe4uroRQCbrO+gNXgdHHO/5BJqc7Qnqu4tlabEB0P+NSXlVo7NAwZgHarCB1wasljFcNvLjAN70Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rumdl/cli-linux-x64-musl": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-linux-x64-musl/-/cli-linux-x64-musl-0.1.30.tgz", + "integrity": "sha512-CDGUBmatxye06D0abeWAbtvXKqVm0RyBd1abtQyVt6070HNvZuS2SXkI3W8oDF1sIFjaVIp0nI4szXlAmZOe2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@rumdl/cli-win32-x64": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@rumdl/cli-win32-x64/-/cli-win32-x64-0.1.30.tgz", + "integrity": "sha512-W6nQZPQRCeN+0nbEbIWdpLSxqkEsDNkGAMaUilMukynmqiT2orJqHHwp9vJmKf1vRg8B8PlxVnL7meumfRk5bg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@shikijs/core": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.22.0.tgz", @@ -15722,6 +15842,28 @@ "points-on-path": "^0.2.1" } }, + "node_modules/rumdl": { + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/rumdl/-/rumdl-0.1.30.tgz", + "integrity": "sha512-vGeJ5oI6LMYbDq9Om6+km1TswecEKPFB0GqAbDfHe3/fzzT8WiAY2lYgLN39e7lzp4GQhzRfnT5OSfiqsILugQ==", + "dev": true, + "license": "MIT", + "bin": { + "rumdl": "bin/rumdl" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "@rumdl/cli-darwin-arm64": "0.1.30", + "@rumdl/cli-darwin-x64": "0.1.30", + "@rumdl/cli-linux-arm64": "0.1.30", + "@rumdl/cli-linux-arm64-musl": "0.1.30", + "@rumdl/cli-linux-x64": "0.1.30", + "@rumdl/cli-linux-x64-musl": "0.1.30", + "@rumdl/cli-win32-x64": "0.1.30" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", diff --git a/package.json b/package.json index da206083..3a0caeae 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,12 @@ "precheck": "astro sync", "check": "astro check", "prelint": "astro sync", - "lint": "npx eslint", - "format": "npm run format:src && npm run format:content", - "format:content": "prettier --write \"**/*.{md,mdx,astro}\"", + "lint": "npm run lint:src", + "lint:src": "npx eslint", + "lint:markdown": "chmod +x node_modules/@rumdl/cli-*/rumdl 2>/dev/null || true && rumdl check .", + "format": "npm run format:src && npm run format:astro && npm run format:markdown", + "format:astro": "npx prettier --write \"**/*.astro\"", + "format:markdown": "chmod +x node_modules/@rumdl/cli-*/rumdl 2>/dev/null || true && rumdl fmt .", "format:src": "npx prettier --write \"**/*.{js,jsx,ts,tsx,mjs,css,json}\"", "linkcheck": "CHECK_LINKS=true astro build", "test": "vitest run" @@ -76,6 +79,7 @@ "react-content-loader": "^7.1.2", "react-dom": "^19.2.4", "react-final-form": "^7.0.0", + "rumdl": "0.1.30", "sass": "^1.97.3", "starlight-image-zoom": "^0.13.0", "starlight-links-validator": "^0.19.2", diff --git a/src/content/docs/online-payments/3ds.mdx b/src/content/docs/online-payments/3ds.mdx index 9765ea69..e86b9236 100644 --- a/src/content/docs/online-payments/3ds.mdx +++ b/src/content/docs/online-payments/3ds.mdx @@ -7,7 +7,6 @@ sidebar: import { Aside } from '@astrojs/starlight/components'; - - ## Configuring Hosted Checkout ### Redirecting Users After Successful Payment @@ -88,7 +86,6 @@ When creating a checkout, simply provide a `redirect_url` parameter to include a Differently from what's stated in our [API docs](/api/checkouts/create), the absence of this parameter does not affect the availability of payment methods in Hosted Checkouts. - ## Hosted Checkout Status Pages With Hosted Checkout, your payment flow is covered from start to finish. All successful payments are presented with a success page, informing users of the completed payment. Hosted Checkout also accommodates other payment outcomes: @@ -101,18 +98,14 @@ With Hosted Checkout, your payment flow is covered from start to finish. All suc A screenshot of the Hosted Checkout payment failed form - - Expired session page is shown for all unpaid checkouts after session expiration or checkout expiration (currently 30 minutes). A screenshot of the Hosted Checkout session expiry form - - Not found page is shown for all URLs that do not match any existing session in our system. A screenshot of the Hosted Checkout page not found form - -