From 5735ebbd76d1c92e91106ff77dd2ab2fa7f23427 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 2 May 2025 16:22:54 -0400 Subject: [PATCH 01/54] Make terms in our dictionary be automatically wrapped in the Definition component --- docusaurus.config.ts | 1 + package.json | 1 + pnpm-lock.yaml | 3 + src/components/Definition/data.ts | 25 ++++++++ src/components/Definition/index.tsx | 55 ++++++++++-------- src/plugins/definition-wrapper.js | 64 +++++++++++++++++++++ src/theme/MDXComponents/index.tsx | 2 + src/theme/MDXPage/index.tsx | 88 +++++++++++++++++++++++++++++ src/theme/MDXPage/styles.module.css | 3 + 9 files changed, 220 insertions(+), 22 deletions(-) create mode 100644 src/plugins/definition-wrapper.js create mode 100644 src/theme/MDXPage/index.tsx create mode 100644 src/theme/MDXPage/styles.module.css diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 71e20b3a1a..f9d07581ba 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -131,6 +131,7 @@ const config = { docs: { sidebarPath: require.resolve("./sidebars.js"), routeBasePath: "/", + rehypePlugins: [require("./src/plugins/definition-wrapper")], editUrl: `${docsRepo}/edit/main`, showLastUpdateAuthor: true, showLastUpdateTime: true, diff --git a/package.json b/package.json index 10ff02149d..0f52503ef6 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "react-hubspot-form": "1.3.7", "react-markdown": "10.1.0", "react-player": "2.16.0", + "unist-util-visit": "^5.0.0", "yaml": "2.7.1", "zod": "3.24.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d7f740da1..31e34020d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,6 +93,9 @@ importers: react-player: specifier: 2.16.0 version: 2.16.0(react@18.3.1) + unist-util-visit: + specifier: ^5.0.0 + version: 5.0.0 yaml: specifier: 2.7.1 version: 2.7.1 diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 1ffc177887..81e406116b 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -23,4 +23,29 @@ export const terms: Term[] = [ "Just-In-Time Single Sign-On Provisioning is a user account provisioning method that automatically creates (or updates) user accounts at the time of login via Single Sign-On, rather than pre-creating all user accounts in advance.", link: "https://en.wikipedia.org/wiki/System_for_Cross-domain_Identity_Management", }, + { + titles: ["K8s", "K8"], + meaning: "K8s is an industry-standard abbreviation for Kubernetes.", + }, + { + titles: ["Ingress"], + meaning: + "An ingress is an entry point into a network for traffic from outside of the network.", + }, + { + titles: ["TCP keepalive", "TCP keep-alive", "TCP keep alive"], + meaning: + "TCP KeepAlive enables TCP connections to remain active even when no data is exchanged between the connected endpoints.", + link: "https://en.wikipedia.org/wiki/Keepalive", + }, + { + titles: ["SaaS"], + meaning: + "SaaS is an industry-standard abbreviation of the term Software as a Service.", + }, + { + titles: ["v3"], + meaning: "v3 is shorthand for the third major version of the ngrok Agent.", + link: "/docs/guides/other-guides/upgrade-v2-v3/", + }, ]; diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index a9d2e33d72..45834b830d 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -5,40 +5,37 @@ import { HoverCardContent, HoverCardTrigger, } from "@ngrok/mantle/hover-card"; -import { QuestionMark } from "@phosphor-icons/react"; +import { + ArrowSquareOut, + LinkSimpleHorizontal, + QuestionMark, +} from "@phosphor-icons/react"; import type React from "react"; import { terms } from "./data"; +import { Icon } from "@ngrok/mantle/icon"; type DefinitionProps = { children: React.ReactNode; meaning?: string; + link?: string; }; export function Definition({ children, meaning, + link, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); - const getMatchingTerm = () => { - const match = terms.find((term) => - term.titles.includes(children.toString()), - ); - if (!match) - throw new Error( - " requires the meaning prop if no corresponding term is found.", - ); - return ( -
-

{match.meaning}

-

- {match.link && ( - - Learn More - - )} -

-
- ); + + // Don't get the match if the meaning or link is provided + const match = + meaning && link + ? null + : terms.find((term) => term.titles.includes(children.toString())); + + const data = { + meaning: meaning || match?.meaning, + link: link || match?.link, }; return ( @@ -58,7 +55,21 @@ export function Definition({ - {meaning || getMatchingTerm()} +
+

{data.meaning}

+ {Boolean(data.link) && ( +

+ + {data?.link?.includes("http") ? ( + } /> + ) : ( + } /> + )} + Learn More + +

+ )} +
); diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js new file mode 100644 index 0000000000..aacde172e6 --- /dev/null +++ b/src/plugins/definition-wrapper.js @@ -0,0 +1,64 @@ +const { visit } = require("unist-util-visit"); +const { terms } = require("../components/Definition/data"); + +module.exports = function remarkWordWrapper(stuff) { + const remainingTerms = terms; + return (tree) => { + const foundTerms = []; + visit(tree, "text", (node, index, parent) => { + let matchingTitle = ""; + const matchingTerm = terms.find((term) => { + matchingTitle = term.titles.find((title) => node.value.includes(title)); + return Boolean(matchingTitle); + }); + + if (!matchingTerm) { + return; + } + + // We only want to match the first instance of this term on the page + if ( + foundTerms.some((term) => + // Case-insensitive check + term.titles + .toLowerCase() + .includes(matchingTitle.toLowerCase()), + ) + ) { + return; + } + + const parts = node.value.split(matchingTitle); + foundTerms.push(matchingTerm); + + return parent.children.splice( + index, + 1, + ...[ + { + type: "text", + value: parts[0], + }, + { + type: "element", + tagName: "Definition", + properties: { + meaning: matchingTerm.meaning, + link: matchingTerm.link, + }, + children: [ + { + type: "text", + value: matchingTitle, + }, + ], + }, + { + type: "text", + value: parts[1], + }, + ], + ); + }); + }; +}; diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 07295ba82c..3b9ba45093 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -11,6 +11,7 @@ import MDXPre from "@theme/MDXComponents/Pre"; import MDXUl from "@theme/MDXComponents/Ul"; import Mermaid from "@theme/Mermaid"; import React, { type ComponentProps } from "react"; +import { Definition } from "@site/src/components/Definition"; const MDXComponents: MDXComponentsObject = { Head, @@ -30,6 +31,7 @@ const MDXComponents: MDXComponentsObject = { h6: (props: ComponentProps<"h6">) => , admonition: Admonition, mermaid: Mermaid, + Definition, }; export default MDXComponents; diff --git a/src/theme/MDXPage/index.tsx b/src/theme/MDXPage/index.tsx new file mode 100644 index 0000000000..edc7d64a90 --- /dev/null +++ b/src/theme/MDXPage/index.tsx @@ -0,0 +1,88 @@ +import React, { type ReactNode } from "react"; +import clsx from "clsx"; +import { + PageMetadata, + HtmlClassNameProvider, + ThemeClassNames, +} from "@docusaurus/theme-common"; +import Layout from "@theme/Layout"; +import MDXContent from "@theme/MDXContent"; +import TOC from "@theme/TOC"; +import ContentVisibility from "@theme/ContentVisibility"; +import type { Props } from "@theme/MDXPage"; + +import EditMetaRow from "@theme/EditMetaRow"; +import styles from "./styles.module.css"; + +export default function MDXPage(props: Props): ReactNode { + const { content: MDXPageContent } = props; + const { metadata, assets } = MDXPageContent; + const { + title, + editUrl, + description, + frontMatter, + lastUpdatedBy, + lastUpdatedAt, + } = metadata; + const { + keywords, + wrapperClassName, + hide_table_of_contents: hideTableOfContents, + } = frontMatter; + const image = assets.image ?? frontMatter.image; + + console.log("Content", MDXPageContent); + + const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy); + + return ( + + + +
+
+
+ +
+ + + +
+ {canDisplayEditMetaRow && ( + + )} +
+ {!hideTableOfContents && MDXPageContent.toc.length > 0 && ( +
+ +
+ )} +
+
+
+
+ ); +} diff --git a/src/theme/MDXPage/styles.module.css b/src/theme/MDXPage/styles.module.css new file mode 100644 index 0000000000..3392df2fe1 --- /dev/null +++ b/src/theme/MDXPage/styles.module.css @@ -0,0 +1,3 @@ +.mdxPageWrapper { + justify-content: center; +} From 14798d9d953426e28913cd18e1fee0e9e1d8a496 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 2 May 2025 16:46:28 -0400 Subject: [PATCH 02/54] Fixed some issues --- docs/whats-new.mdx | 2 +- src/components/Definition/data.ts | 2 +- src/plugins/definition-wrapper.js | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/whats-new.mdx b/docs/whats-new.mdx index 83d8285838..a7d8058cce 100644 --- a/docs/whats-new.mdx +++ b/docs/whats-new.mdx @@ -14,7 +14,7 @@ You can expect this page to update regularly (at least monthly). We'll include t ## March 2025 -- 2025-03-13 - Agent now supports TCP KeepAlive configuration. +- 2025-03-13 - Agent now supports TCP-KeepAlive configuration. ## February 2025 diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 81e406116b..5eb9f1bdf8 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -33,7 +33,7 @@ export const terms: Term[] = [ "An ingress is an entry point into a network for traffic from outside of the network.", }, { - titles: ["TCP keepalive", "TCP keep-alive", "TCP keep alive"], + titles: ["TCP KeepAlive", "TCP Keep-Alive", "TCP Keep Alive"], meaning: "TCP KeepAlive enables TCP connections to remain active even when no data is exchanged between the connected endpoints.", link: "https://en.wikipedia.org/wiki/Keepalive", diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index aacde172e6..607f4aa4db 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -8,7 +8,12 @@ module.exports = function remarkWordWrapper(stuff) { visit(tree, "text", (node, index, parent) => { let matchingTitle = ""; const matchingTerm = terms.find((term) => { - matchingTitle = term.titles.find((title) => node.value.includes(title)); + matchingTitle = term.titles.find((title) => + // Case-insensitive check + node.value + ?.toLowerCase() + .includes(title?.toLowerCase()), + ); return Boolean(matchingTitle); }); @@ -18,12 +23,7 @@ module.exports = function remarkWordWrapper(stuff) { // We only want to match the first instance of this term on the page if ( - foundTerms.some((term) => - // Case-insensitive check - term.titles - .toLowerCase() - .includes(matchingTitle.toLowerCase()), - ) + foundTerms.some((term) => term.titles[0] === matchingTerm.titles[0]) ) { return; } From 5e3f1f18de0e1fd4602405f89cd3ac995818f25a Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 20:47:37 +0000 Subject: [PATCH 03/54] ci: apply automated fixes --- src/components/Definition/index.tsx | 2 +- src/theme/MDXComponents/index.tsx | 2 +- src/theme/MDXPage/index.tsx | 10 +++++----- src/theme/MDXPage/styles.module.css | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 45834b830d..f3c5600b8d 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -5,6 +5,7 @@ import { HoverCardContent, HoverCardTrigger, } from "@ngrok/mantle/hover-card"; +import { Icon } from "@ngrok/mantle/icon"; import { ArrowSquareOut, LinkSimpleHorizontal, @@ -12,7 +13,6 @@ import { } from "@phosphor-icons/react"; import type React from "react"; import { terms } from "./data"; -import { Icon } from "@ngrok/mantle/icon"; type DefinitionProps = { children: React.ReactNode; diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 3b9ba45093..3f1a78c7f7 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,4 +1,5 @@ import Head from "@docusaurus/Head"; +import { Definition } from "@site/src/components/Definition"; import Admonition from "@theme/Admonition"; import type { MDXComponentsObject } from "@theme/MDXComponents"; import MDXA from "@theme/MDXComponents/A"; @@ -11,7 +12,6 @@ import MDXPre from "@theme/MDXComponents/Pre"; import MDXUl from "@theme/MDXComponents/Ul"; import Mermaid from "@theme/Mermaid"; import React, { type ComponentProps } from "react"; -import { Definition } from "@site/src/components/Definition"; const MDXComponents: MDXComponentsObject = { Head, diff --git a/src/theme/MDXPage/index.tsx b/src/theme/MDXPage/index.tsx index edc7d64a90..36d2017706 100644 --- a/src/theme/MDXPage/index.tsx +++ b/src/theme/MDXPage/index.tsx @@ -1,15 +1,15 @@ -import React, { type ReactNode } from "react"; -import clsx from "clsx"; import { - PageMetadata, HtmlClassNameProvider, + PageMetadata, ThemeClassNames, } from "@docusaurus/theme-common"; +import ContentVisibility from "@theme/ContentVisibility"; import Layout from "@theme/Layout"; import MDXContent from "@theme/MDXContent"; -import TOC from "@theme/TOC"; -import ContentVisibility from "@theme/ContentVisibility"; import type { Props } from "@theme/MDXPage"; +import TOC from "@theme/TOC"; +import clsx from "clsx"; +import React, { type ReactNode } from "react"; import EditMetaRow from "@theme/EditMetaRow"; import styles from "./styles.module.css"; diff --git a/src/theme/MDXPage/styles.module.css b/src/theme/MDXPage/styles.module.css index 3392df2fe1..dd0b7f3ac9 100644 --- a/src/theme/MDXPage/styles.module.css +++ b/src/theme/MDXPage/styles.module.css @@ -1,3 +1,3 @@ .mdxPageWrapper { - justify-content: center; + justify-content: center; } From f94ee7aacea0cf85b7f7386a425c366ae47da3c1 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 7 May 2025 14:55:29 -0400 Subject: [PATCH 04/54] Fixed style and removed use of the component where unnecessary --- docs/iam/users.mdx | 5 ++--- src/components/Definition/index.tsx | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/iam/users.mdx b/docs/iam/users.mdx index 03e4149ae5..f0957595ab 100644 --- a/docs/iam/users.mdx +++ b/docs/iam/users.mdx @@ -1,4 +1,3 @@ -import { Definition } from "/src/components/Definition/"; # Users @@ -50,7 +49,7 @@ additional details on configuring it. In addition to the normal authentication factors required to log into the ngrok dashboard, you may also configure your ngrok account to further restrict -dashboard access to a set of IP CIDR blocks. +dashboard access to a set of IP CIDR blocks. Dashboard IP Restrictions should always be used in a warning mode first to test that you won't accidentally lock yourself out of your account if you restrict @@ -107,7 +106,7 @@ Settings page](https://dashboard.ngrok.com/settings). By default, you provision new users by inviting them to join your Account with Invitations. If you have configured [SSO](#single-sign-on), you may also add users to your -account via the SCIM or JIT provisioning methods. +account via the SCIM or JIT provisioning methods. ### Invitations diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index f3c5600b8d..9e0ea13d25 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -54,11 +54,11 @@ export function Definition({ - -
-

{data.meaning}

+ +
+ {data.meaning} {Boolean(data.link) && ( -

+ {data?.link?.includes("http") ? ( } /> @@ -67,7 +67,7 @@ export function Definition({ )} Learn More -

+ )}
From 0df0fc181c536304beb819738ecc5c9f46a05e19 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 7 May 2025 16:46:02 -0400 Subject: [PATCH 05/54] Okay it's pretty much ready --- src/components/Definition/data.ts | 26 +++++++++++++++++--------- src/plugins/definition-wrapper.js | 30 +++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 5eb9f1bdf8..214d3a1fc6 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -2,11 +2,12 @@ export type Term = { titles: string[]; meaning: string; link?: string; + caseSensitive?: boolean; }; export const terms: Term[] = [ { - titles: ["CIDR", "IP CIDR"], + titles: ["IP CIDR", "CIDRs", "CIDR"], meaning: "Classless Inter-Domain Routing is a method used to allocate IP addresses more efficiently and route IP packets more flexibly than the older class-based system.", link: "https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing", @@ -28,24 +29,31 @@ export const terms: Term[] = [ meaning: "K8s is an industry-standard abbreviation for Kubernetes.", }, { - titles: ["Ingress"], + titles: ["Ingress", "Ingresses"], meaning: "An ingress is an entry point into a network for traffic from outside of the network.", }, { - titles: ["TCP KeepAlive", "TCP Keep-Alive", "TCP Keep Alive"], + titles: [ + "TCP-KeepAlive", + "TCP KeepAlive", + "TCP Keep-Alive", + "TCP Keep Alive", + ], meaning: "TCP KeepAlive enables TCP connections to remain active even when no data is exchanged between the connected endpoints.", link: "https://en.wikipedia.org/wiki/Keepalive", }, - { - titles: ["SaaS"], - meaning: - "SaaS is an industry-standard abbreviation of the term Software as a Service.", - }, { titles: ["v3"], + caseSensitive: true, meaning: "v3 is shorthand for the third major version of the ngrok Agent.", - link: "/docs/guides/other-guides/upgrade-v2-v3/", + link: "/docs/agent/config/v3", + }, + { + titles: ["v2"], + caseSensitive: true, + meaning: "v2 is shorthand for the second major version of the ngrok Agent.", + link: "/docs/agent/config/v2", }, ]; diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 607f4aa4db..570f297341 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -6,13 +6,33 @@ module.exports = function remarkWordWrapper(stuff) { return (tree) => { const foundTerms = []; visit(tree, "text", (node, index, parent) => { + if (!node?.value) { + return; + } + + if ( + parent?.tagName?.startsWith("h") || + parent?.tagName === "a" || + parent?.tagName === "Link" + ) { + // Don't wrap terms in headings or links + return; + } let matchingTitle = ""; const matchingTerm = terms.find((term) => { - matchingTitle = term.titles.find((title) => - // Case-insensitive check - node.value - ?.toLowerCase() - .includes(title?.toLowerCase()), + let termIndex; + const nodeValue = term.caseSensitive + ? node.value + : node.value.toLowerCase(); + const foundTitle = term.titles.find((title) => { + const titleValue = term.caseSensitive ? title : title.toLowerCase(); + termIndex = nodeValue.indexOf(titleValue); + return Boolean(termIndex !== -1); + }); + if (!foundTitle) return false; + matchingTitle = node.value.slice( + termIndex, + termIndex + foundTitle.length, ); return Boolean(matchingTitle); }); From 7ec8d39d7d733365e3a5ada263481e62764ca2dd Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 7 May 2025 16:50:38 -0400 Subject: [PATCH 06/54] Last optimization --- src/plugins/definition-wrapper.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 570f297341..2b041452bf 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -15,11 +15,17 @@ module.exports = function remarkWordWrapper(stuff) { parent?.tagName === "a" || parent?.tagName === "Link" ) { - // Don't wrap terms in headings or links + // Skip terms in headings or links return; } let matchingTitle = ""; const matchingTerm = terms.find((term) => { + /** + * Find the first term that matches the node value + * and is not already found in the foundTerms array. + * We use indexOf so we can pull the exact term out + * of the node value. + */ let termIndex; const nodeValue = term.caseSensitive ? node.value @@ -49,6 +55,10 @@ module.exports = function remarkWordWrapper(stuff) { } const parts = node.value.split(matchingTitle); + if (parts.length < 2) { + // If the term is not found in the text, return + return; + } foundTerms.push(matchingTerm); return parent.children.splice( From bf4b237fb0fa2c241f34f117f61d847547231039 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 7 May 2025 20:50:30 +0000 Subject: [PATCH 07/54] ci: apply automated fixes --- docs/iam/users.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/iam/users.mdx b/docs/iam/users.mdx index f0957595ab..860db8010d 100644 --- a/docs/iam/users.mdx +++ b/docs/iam/users.mdx @@ -1,4 +1,3 @@ - # Users Users are members of your Account that may log into the dashboard, start From 8757f2bee28d4fcd3870b741294cb2e449b8bab9 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 8 May 2025 10:15:02 -0400 Subject: [PATCH 08/54] It works; added some terms --- src/components/Definition/data.ts | 12 +++++++++ src/components/Definition/index.tsx | 5 +++- src/plugins/definition-wrapper.js | 42 ++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 214d3a1fc6..789b9d8859 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -56,4 +56,16 @@ export const terms: Term[] = [ meaning: "v2 is shorthand for the second major version of the ngrok Agent.", link: "/docs/agent/config/v2", }, + { + titles: ["OWASP"], + meaning: + "OWASP: The Open Web Application Security Project. This non-profit organization is dedicated to improving software security through providing resources, tools, and community support.", + link: "https://owasp.org/about/", + }, + { + titles: ["Helm"], + meaning: + "Helm is a package manager for Kubernetes that simplifies the deployment and management of applications on Kubernetes clusters.", + link: "https://helm.sh/docs/", + }, ]; diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 9e0ea13d25..867ceea91e 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -13,17 +13,20 @@ import { } from "@phosphor-icons/react"; import type React from "react"; import { terms } from "./data"; +import clsx from "clsx"; type DefinitionProps = { children: React.ReactNode; meaning?: string; link?: string; + className?: string; }; export function Definition({ children, meaning, link, + className, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); @@ -48,7 +51,7 @@ export function Definition({ appearance="link" > <> - {children} + {children} diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 2b041452bf..8b03a6b30e 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -1,3 +1,5 @@ +import { match } from "assert"; + const { visit } = require("unist-util-visit"); const { terms } = require("../components/Definition/data"); @@ -13,13 +15,20 @@ module.exports = function remarkWordWrapper(stuff) { if ( parent?.tagName?.startsWith("h") || parent?.tagName === "a" || - parent?.tagName === "Link" + parent?.tagName === "Link" || + parent?.tagName === "Definition" || + parent?.tagName === "code" || + parent?.tagName === "pre" ) { - // Skip terms in headings or links + // Skip terms in certain tags return; } let matchingTitle = ""; const matchingTerm = terms.find((term) => { + // We only want to match the first instance of this term on the page + if (foundTerms.some((fTerm) => fTerm.titles[0] === term.titles[0])) { + return; + } /** * Find the first term that matches the node value * and is not already found in the foundTerms array. @@ -27,11 +36,10 @@ module.exports = function remarkWordWrapper(stuff) { * of the node value. */ let termIndex; - const nodeValue = term.caseSensitive - ? node.value - : node.value.toLowerCase(); + const { caseSensitive } = term; + const nodeValue = caseSensitive ? node.value : node.value.toLowerCase(); const foundTitle = term.titles.find((title) => { - const titleValue = term.caseSensitive ? title : title.toLowerCase(); + const titleValue = caseSensitive ? title : title.toLowerCase(); termIndex = nodeValue.indexOf(titleValue); return Boolean(termIndex !== -1); }); @@ -43,14 +51,11 @@ module.exports = function remarkWordWrapper(stuff) { return Boolean(matchingTitle); }); - if (!matchingTerm) { - return; + if (node.value.includes("unified ingress platform")) { + console.log("Found it", matchingTerm); } - // We only want to match the first instance of this term on the page - if ( - foundTerms.some((term) => term.titles[0] === matchingTerm.titles[0]) - ) { + if (!matchingTerm) { return; } @@ -61,6 +66,18 @@ module.exports = function remarkWordWrapper(stuff) { } foundTerms.push(matchingTerm); + let styles = ""; + if (parent?.properties?.className) { + styles += `${parent.properties.className} `; + } + if (parent.tagName === "strong") { + styles += "font-bold "; + } + + if (parent.tagName === "em") { + styles += "italic "; + } + return parent.children.splice( index, 1, @@ -75,6 +92,7 @@ module.exports = function remarkWordWrapper(stuff) { properties: { meaning: matchingTerm.meaning, link: matchingTerm.link, + className: styles, }, children: [ { From a3e89843a43f00fa5a1b262702c0c3547c1ba5bc Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 8 May 2025 10:42:56 -0400 Subject: [PATCH 09/54] remove bad import --- src/plugins/definition-wrapper.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 8b03a6b30e..5ab58cb0bd 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -1,5 +1,3 @@ -import { match } from "assert"; - const { visit } = require("unist-util-visit"); const { terms } = require("../components/Definition/data"); From fb56c8cf4064aad63b1273479fca46c1ae77e3a5 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 16:47:45 +0000 Subject: [PATCH 10/54] ci: apply automated fixes --- src/components/Definition/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index ed48ce0463..fdba4370ad 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -1,4 +1,5 @@ import Link from "@docusaurus/Link"; +import { useLocation } from "@docusaurus/router"; import { Button } from "@ngrok/mantle/button"; import { HoverCard, @@ -11,10 +12,9 @@ import { LinkSimpleHorizontal, QuestionMark, } from "@phosphor-icons/react"; +import clsx from "clsx"; import type React from "react"; import { terms } from "./data"; -import clsx from "clsx"; -import { useLocation } from "@docusaurus/router"; type DefinitionProps = { children: React.ReactNode; From 7d12840bf8468c91ec37421be4db11d36287b5b1 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 8 May 2025 12:47:59 -0400 Subject: [PATCH 11/54] More optimizations --- docs/k8s/installation/install.mdx | 5 +- src/components/Definition/data.ts | 56 ++++++++++++++++-- src/components/Definition/index.tsx | 22 ++++++- src/plugins/definition-wrapper.js | 92 +++++++++++++++++++---------- 4 files changed, 133 insertions(+), 42 deletions(-) diff --git a/docs/k8s/installation/install.mdx b/docs/k8s/installation/install.mdx index a0b4bb2075..355c3ea764 100644 --- a/docs/k8s/installation/install.mdx +++ b/docs/k8s/installation/install.mdx @@ -58,9 +58,8 @@ export NAMESPACE=ngrok-operator ### 4. (Optional) Install Gateway API CRDs If you plan on using the Gateway API CRDs with the ngrok Kubernetes operator, install them before the operator. -When the operator starts up it will enable support for Gateway API if the Gateway API CRDs are detected in your cluster. -If you do not plan on using the Gateway API, then you can ignore this optional step. -The Gateway API CRDs can be installed at a later point, but you will need to restart the operator after installing the Gateway API CRDs + +When the operator starts up it will enable support for Gateway API if the Gateway API CRDs are detected in your cluster. If you do not plan on using the Gateway API, then you can ignore this optional step. The Gateway API CRDs can be installed at a later point, but you will need to restart the operator after installing the Gateway API CRDs for the Gateway API support to be enabled. You can select either the standard or experimental set of Gateway API CRDs depending on your preference. Either version will work with the ngrok Kubernetes operator. diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 789b9d8859..beef2dcef7 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -3,14 +3,19 @@ export type Term = { meaning: string; link?: string; caseSensitive?: boolean; + // If the term can be pluralized, this is the ending to use. + // For example, "IP CIDR" -> "IP CIDRs", so pluralEnding = "s" + // "Ingress" -> "Ingresses", so pluralEnding = "es" + pluralEnding?: string; }; export const terms: Term[] = [ { - titles: ["IP CIDR", "CIDRs", "CIDR"], + titles: ["IP CIDR", "CIDR"], meaning: "Classless Inter-Domain Routing is a method used to allocate IP addresses more efficiently and route IP packets more flexibly than the older class-based system.", link: "https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing", + pluralEnding: "s", }, { titles: ["SCIM", "SCIM provisioning"], @@ -19,19 +24,21 @@ export const terms: Term[] = [ link: "https://en.wikipedia.org/wiki/System_for_Cross-domain_Identity_Management", }, { - titles: ["JIT", "JIT provisioning"], + titles: ["JIT provisioning"], meaning: "Just-In-Time Single Sign-On Provisioning is a user account provisioning method that automatically creates (or updates) user accounts at the time of login via Single Sign-On, rather than pre-creating all user accounts in advance.", link: "https://en.wikipedia.org/wiki/System_for_Cross-domain_Identity_Management", }, { - titles: ["K8s", "K8"], + titles: ["K8"], meaning: "K8s is an industry-standard abbreviation for Kubernetes.", + pluralEnding: "s", }, { - titles: ["Ingress", "Ingresses"], + titles: ["Ingress"], meaning: "An ingress is an entry point into a network for traffic from outside of the network.", + pluralEnding: "es", }, { titles: [ @@ -66,6 +73,45 @@ export const terms: Term[] = [ titles: ["Helm"], meaning: "Helm is a package manager for Kubernetes that simplifies the deployment and management of applications on Kubernetes clusters.", - link: "https://helm.sh/docs/", + link: "https://helm.sh/", + }, + { + titles: ["TLS Termination"], + meaning: + "TLS termination is the process of decrypting incoming TLS (Transport Layer Security) traffic at a server or load balancer before passing the unencrypted traffic to internal systems.", + link: "/docs/universal-gateway/tls-termination/", + }, + { + titles: ["Gateway API CRD", "Gateway API"], + link: "https://gateway-api.sigs.k8s.io/guides/", + meaning: + "Gateway API CRDs (Custom Resource Definitions) are a set of standardized, extensible resources that define and manage networking configurations like routing, gateways, and traffic policies in a more expressive and role-oriented way than Ingress.", + pluralEnding: "s", + }, + { + titles: ["CRD", "Custom Resource Definition"], + meaning: + "CustomResourceDefinitions allow users to extend the Kubernetes API by defining their own resource types.", + link: "https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/", + pluralEnding: "s", + }, + { + titles: ["ALPN"], + link: "https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation", + meaning: + "ALPN (Application-Layer Protocol Negotiation) allows a client and server to negotiate which application protocol (like HTTP/2 or HTTP/1.1) to use over a secure connection during the TLS handshake.", + }, + { + titles: ["SNI"], + link: "https://en.wikipedia.org/wiki/Server_Name_Indication", + meaning: + "SNI (Server Name Indication) is a TLS extension that allows a client to specify the hostname it is trying to connect to during the TLS handshake, enabling servers to present the correct SSL/TLS certificate for that hostname.", + }, + { + titles: ["CEL"], + caseSensitive: true, + link: "https://github.com/google/cel-spec/tree/master?tab=readme-ov-file#common-expression-language", + meaning: + "CEL (Common Expression Language) is a fast, safe, and portable expression language developed by Google for evaluating expressions in configuration, policy, and runtime environments.", }, ]; diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 867ceea91e..ed48ce0463 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -14,6 +14,7 @@ import { import type React from "react"; import { terms } from "./data"; import clsx from "clsx"; +import { useLocation } from "@docusaurus/router"; type DefinitionProps = { children: React.ReactNode; @@ -29,16 +30,31 @@ export function Definition({ className, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); + const linkType = link?.startsWith("http") + ? "external" + : link?.startsWith("/") + ? "internal" + : null; + if (link && !linkType) + throw new Error(` link must be a valid URL. Received ${link}`); + + if (link?.includes("localhost:")) + throw new Error( + ` link must not be a localhost URL. Received ${link}`, + ); + + const { pathname } = useLocation(); // Don't get the match if the meaning or link is provided const match = meaning && link ? null : terms.find((term) => term.titles.includes(children.toString())); - const data = { meaning: meaning || match?.meaning, - link: link || match?.link, + // If link is to the current page, don't use it. No need to + // link to the same page. + link: !link ? null : pathname?.includes(link) ? null : link || match?.link, }; return ( @@ -63,7 +79,7 @@ export function Definition({ {Boolean(data.link) && ( - {data?.link?.includes("http") ? ( + {linkType === "external" ? ( } /> ) : ( } /> diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 5ab58cb0bd..7e2978c05b 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -1,6 +1,48 @@ const { visit } = require("unist-util-visit"); const { terms } = require("../components/Definition/data"); +function findSpecialIndex(str, text) { + // Get the index of the first occurrence of the text in str, + // so long as text doesn't start with a letter or number + const escapedText = text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // Escape special regex characters + const regex = new RegExp(`(?:^|\\n|\\s|-)(${escapedText})`, "g"); + const match = regex.exec(str); + return match ? match.index + match[0].indexOf(match[1]) : -1; +} + +function parentIsForbiddenTag(tagName) { + // Check if the tag name is in the list of forbidden tags + const forbiddenTags = [ + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "a", + "Link", + "Definition", + "code", + "pre", + ]; + return forbiddenTags.includes(tagName); +} + +function getStyles(parent) { + let styles = ""; + if (parent?.properties?.className) { + styles += `${parent.properties.className} `; + } + if (parent.tagName === "strong") { + styles += "font-bold "; + } + + if (parent.tagName === "em") { + styles += "italic "; + } + return styles; +} + module.exports = function remarkWordWrapper(stuff) { const remainingTerms = terms; return (tree) => { @@ -10,14 +52,7 @@ module.exports = function remarkWordWrapper(stuff) { return; } - if ( - parent?.tagName?.startsWith("h") || - parent?.tagName === "a" || - parent?.tagName === "Link" || - parent?.tagName === "Definition" || - parent?.tagName === "code" || - parent?.tagName === "pre" - ) { + if (parentIsForbiddenTag(parent.tagName)) { // Skip terms in certain tags return; } @@ -33,26 +68,31 @@ module.exports = function remarkWordWrapper(stuff) { * We use indexOf so we can pull the exact term out * of the node value. */ - let termIndex; - const { caseSensitive } = term; + let termStartIndex; + const { caseSensitive, pluralEnding } = term; const nodeValue = caseSensitive ? node.value : node.value.toLowerCase(); const foundTitle = term.titles.find((title) => { const titleValue = caseSensitive ? title : title.toLowerCase(); - termIndex = nodeValue.indexOf(titleValue); - return Boolean(termIndex !== -1); + termStartIndex = findSpecialIndex(nodeValue, titleValue); + return Boolean(termStartIndex !== -1); }); if (!foundTitle) return false; - matchingTitle = node.value.slice( - termIndex, - termIndex + foundTitle.length, - ); + let termEndIndex = termStartIndex + foundTitle.length; + + // Check if the term has a plural ending, and if the + // word we found in the node value has that plural ending + if ( + pluralEnding && + node.value.slice(termEndIndex, termEndIndex + pluralEnding.length) === + pluralEnding + ) { + termEndIndex += pluralEnding.length; + } + + matchingTitle = node.value.slice(termStartIndex, termEndIndex); return Boolean(matchingTitle); }); - if (node.value.includes("unified ingress platform")) { - console.log("Found it", matchingTerm); - } - if (!matchingTerm) { return; } @@ -64,17 +104,7 @@ module.exports = function remarkWordWrapper(stuff) { } foundTerms.push(matchingTerm); - let styles = ""; - if (parent?.properties?.className) { - styles += `${parent.properties.className} `; - } - if (parent.tagName === "strong") { - styles += "font-bold "; - } - - if (parent.tagName === "em") { - styles += "italic "; - } + const styles = getStyles(parent); return parent.children.splice( index, From 5e2e6b7944d020786418dae49042f3bab0b5efa2 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 8 May 2025 12:51:00 -0400 Subject: [PATCH 12/54] fix types issue --- src/components/Definition/index.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index ed48ce0463..3fa93869d3 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -54,7 +54,11 @@ export function Definition({ meaning: meaning || match?.meaning, // If link is to the current page, don't use it. No need to // link to the same page. - link: !link ? null : pathname?.includes(link) ? null : link || match?.link, + link: !link + ? undefined + : pathname?.includes(link) + ? undefined + : link || match?.link, }; return ( @@ -76,7 +80,7 @@ export function Definition({
{data.meaning} - {Boolean(data.link) && ( + {Boolean(data?.link) && ( {linkType === "external" ? ( From 68835db21594c3de1c42ed46fdbbedc320f7de79 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 8 May 2025 13:14:13 -0400 Subject: [PATCH 13/54] Fix text --- docs/k8s/installation/install.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/k8s/installation/install.mdx b/docs/k8s/installation/install.mdx index 355c3ea764..8a15570e64 100644 --- a/docs/k8s/installation/install.mdx +++ b/docs/k8s/installation/install.mdx @@ -59,8 +59,7 @@ export NAMESPACE=ngrok-operator If you plan on using the Gateway API CRDs with the ngrok Kubernetes operator, install them before the operator. -When the operator starts up it will enable support for Gateway API if the Gateway API CRDs are detected in your cluster. If you do not plan on using the Gateway API, then you can ignore this optional step. The Gateway API CRDs can be installed at a later point, but you will need to restart the operator after installing the Gateway API CRDs -for the Gateway API support to be enabled. +When the operator starts up it will enable support for Gateway API if the Gateway API CRDs are detected in your cluster. If you do not plan on using the Gateway API, then you can ignore this optional step. The Gateway API CRDs can be installed at a later point, but you will need to restart the operator after installing the Gateway API CRDs for the Gateway API support to be enabled. You can select either the standard or experimental set of Gateway API CRDs depending on your preference. Either version will work with the ngrok Kubernetes operator. From 899b010d091fd6a6ea0386f623a4a17bff41507e Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 8 May 2025 14:31:24 -0400 Subject: [PATCH 14/54] Fix font size --- src/components/Definition/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 96b6b30942..5bd93681fa 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -82,7 +82,10 @@ export function Definition({ {data.meaning} {Boolean(data?.link) && ( - + {linkType === "external" ? ( } /> ) : ( From 7e61c98067d27069bc180b55400d3ded920ef0a2 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 14 May 2025 16:11:11 -0400 Subject: [PATCH 15/54] Fix font size and icon size --- src/components/Definition/index.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 5bd93681fa..8c80261f0f 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -61,6 +61,8 @@ export function Definition({ : link || match?.link, }; + const iconSize = 4; + return ( @@ -83,14 +85,19 @@ export function Definition({ {Boolean(data?.link) && ( - {linkType === "external" ? ( - } /> - ) : ( - } /> - )} +
+ {linkType === "external" ? ( + } /> + ) : ( + } + /> + )} +
Learn More
From 93d4c7300103fb1fb0f4cc353a87132975be278e Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 14 May 2025 17:05:03 -0400 Subject: [PATCH 16/54] Fix capitalization of tabs; move lang switcher tabs to the right --- package.json | 2 ++ pnpm-lock.yaml | 16 ++++++++++++++++ src/components/CodeBlockWithInfo/index.tsx | 10 +++++----- src/components/LangSwitcher/index.tsx | 5 ++--- src/components/code-block.tsx | 20 ++++++++++++++------ src/theme/CodeBlock/index.tsx | 2 +- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 56383e5101..3569148c04 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,9 @@ "@ngrok/mantle": "0.27.2", "@phosphor-icons/react": "2.1.7", "@stackql/docusaurus-plugin-hubspot": "1.1.0", + "@types/capitalize": "^2.0.2", "algoliasearch": "5.24.0", + "capitalize": "^2.0.4", "clsx": "2.1.1", "concurrently": "9.1.2", "cross-env": "7.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 362733c6bb..b2916c40d8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,9 +57,15 @@ importers: '@stackql/docusaurus-plugin-hubspot': specifier: 1.1.0 version: 1.1.0 + '@types/capitalize': + specifier: ^2.0.2 + version: 2.0.2 algoliasearch: specifier: 5.24.0 version: 5.24.0 + capitalize: + specifier: ^2.0.4 + version: 2.0.4 clsx: specifier: 2.1.1 version: 2.1.1 @@ -2378,6 +2384,9 @@ packages: '@types/bonjour@3.5.13': resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + '@types/capitalize@2.0.2': + resolution: {integrity: sha512-J3I2HyJL4ui26Nwg6fQHx+1pg4Mn0i25T2Q1DIE1fyfySERXlT7j0F06gI52COlt8J26YETAWUCzrWNH/F/PeA==} + '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} @@ -3013,6 +3022,9 @@ packages: caniuse-lite@1.0.30001717: resolution: {integrity: sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==} + capitalize@2.0.4: + resolution: {integrity: sha512-wcSyiFqXRYyCoqu0o0ekXzJAKCLMkqWS5QWGlgTJFJKwRmI6pzcN2hBl5VPq9RzLW5Uf4FF/V/lcFfjCtVak2w==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -10078,6 +10090,8 @@ snapshots: dependencies: '@types/node': 22.15.3 + '@types/capitalize@2.0.2': {} + '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.6 @@ -10846,6 +10860,8 @@ snapshots: caniuse-lite@1.0.30001717: {} + capitalize@2.0.4: {} + ccount@2.0.1: {} chai@5.2.0: diff --git a/src/components/CodeBlockWithInfo/index.tsx b/src/components/CodeBlockWithInfo/index.tsx index 4881fb3483..f0e7d83e77 100644 --- a/src/components/CodeBlockWithInfo/index.tsx +++ b/src/components/CodeBlockWithInfo/index.tsx @@ -50,12 +50,8 @@ export function CodeBlockWithInfo({
- {headerContent} - {info && } - - {meta?.title && ( -
+
<> {meta?.mode ? ( @@ -74,6 +70,10 @@ export function CodeBlockWithInfo({
)} + {headerContent} + {info && } + + {!meta?.disableCopy && } export function LangSwitcher({ children, className, ...props }: any) { @@ -66,9 +67,7 @@ export function LangSwitcher({ children, className, ...props }: any) { ? "bg-neutral-500/10 text-neutral-800" : "text-neutral-500", )} - tabText={ - child?.meta.tabName || child?.language.toUpperCase() - } + tabText={child?.meta.tabName || capitalize(child?.language)} /> ); })} diff --git a/src/components/code-block.tsx b/src/components/code-block.tsx index 27b9ff1aff..48671c6992 100644 --- a/src/components/code-block.tsx +++ b/src/components/code-block.tsx @@ -9,6 +9,7 @@ import type { ComponentProps, ReactNode } from "react"; import { CodeBlockWithInfo } from "./CodeBlockWithInfo"; import { LangTab } from "./LangSwitcher/LangTab"; import { getLanguageInfo, getMetaData } from "./LangSwitcher/utils"; +import capitalize from "capitalize"; type WithIndentation = Pick< ComponentProps, @@ -70,19 +71,26 @@ function DocsCodeBlock({ metastring ? `${className} ${metastring}` : className, ); + if (className?.includes("mb")) { + console.log("Classname", className); + } + return ( + <> + {meta.title && {meta.title}} + + } info={getLanguageInfo(language)} codeBlockProps={props} diff --git a/src/theme/CodeBlock/index.tsx b/src/theme/CodeBlock/index.tsx index afece5ba9b..b223b7004a 100644 --- a/src/theme/CodeBlock/index.tsx +++ b/src/theme/CodeBlock/index.tsx @@ -12,7 +12,7 @@ export default function CodeBlock({ className, ...props }: Props) { Loading… } > - {() => } + {() => } ); } From e6b1cf3542d2b980f011f7ee65e8626506c297c8 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 14 May 2025 21:04:49 +0000 Subject: [PATCH 17/54] ci: apply automated fixes --- src/components/LangSwitcher/index.tsx | 2 +- src/components/code-block.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LangSwitcher/index.tsx b/src/components/LangSwitcher/index.tsx index ad2fbb62f8..974fee0474 100644 --- a/src/components/LangSwitcher/index.tsx +++ b/src/components/LangSwitcher/index.tsx @@ -1,4 +1,5 @@ import BrowserOnly from "@docusaurus/BrowserOnly"; +import capitalize from "capitalize"; import clsx from "clsx"; import { useContext } from "react"; import { CodeBlockWithInfo } from "../CodeBlockWithInfo"; @@ -8,7 +9,6 @@ import LangSwitcherContext, { } from "./LangSwitcherContext"; import { LangTab } from "./LangTab"; import { getCodeBlocks, languagesAreSynonyms } from "./utils"; -import capitalize from "capitalize"; // biome-ignore lint/suspicious/noExplicitAny: export function LangSwitcher({ children, className, ...props }: any) { diff --git a/src/components/code-block.tsx b/src/components/code-block.tsx index 48671c6992..83454e234f 100644 --- a/src/components/code-block.tsx +++ b/src/components/code-block.tsx @@ -5,11 +5,11 @@ import type { } from "@ngrok/mantle/code-block"; import { CodeBlock, parseLanguage } from "@ngrok/mantle/code-block"; import type { WithStyleProps } from "@ngrok/mantle/types"; +import capitalize from "capitalize"; import type { ComponentProps, ReactNode } from "react"; import { CodeBlockWithInfo } from "./CodeBlockWithInfo"; import { LangTab } from "./LangSwitcher/LangTab"; import { getLanguageInfo, getMetaData } from "./LangSwitcher/utils"; -import capitalize from "capitalize"; type WithIndentation = Pick< ComponentProps, From 5a8c9b6daff6a0e6f05953e1fbb7ca497723d827 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 12 Jun 2025 14:57:16 -0400 Subject: [PATCH 18/54] Update index.tsx --- src/components/Definition/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 8c80261f0f..c875045390 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -71,6 +71,7 @@ export function Definition({ type="button" priority="neutral" appearance="link" + aria-label={children.toString()} > <> {children} From 00a75fe8130a30c8145885f7ec1af516e09f4152 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 11:48:39 -0400 Subject: [PATCH 19/54] Auto-include custom components --- src/theme/MDXComponents/index.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 3f1a78c7f7..92840a1e7c 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,5 +1,10 @@ import Head from "@docusaurus/Head"; import { Definition } from "@site/src/components/Definition"; +import TabItem from "@theme/TabItem"; +import Tabs from "@theme/Tabs"; +import ConfigExample from "@site/src/components/ConfigExample"; +import { YouTubeEmbed } from "@components/youtube-embed"; +import { LangSwitcher } from "./LangSwitcher"; import Admonition from "@theme/Admonition"; import type { MDXComponentsObject } from "@theme/MDXComponents"; import MDXA from "@theme/MDXComponents/A"; @@ -32,6 +37,11 @@ const MDXComponents: MDXComponentsObject = { admonition: Admonition, mermaid: Mermaid, Definition, + Tabs, + TabItem, + ConfigExample, + YouTubeEmbed, + LangSwitcher, }; export default MDXComponents; From 1d05495ce5ca5dee0397e9255906637f739ec1b9 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 15:49:40 +0000 Subject: [PATCH 20/54] ci: apply automated fixes --- src/theme/MDXComponents/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 92840a1e7c..47e8388289 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,10 +1,7 @@ +import { YouTubeEmbed } from "@components/youtube-embed"; import Head from "@docusaurus/Head"; -import { Definition } from "@site/src/components/Definition"; -import TabItem from "@theme/TabItem"; -import Tabs from "@theme/Tabs"; import ConfigExample from "@site/src/components/ConfigExample"; -import { YouTubeEmbed } from "@components/youtube-embed"; -import { LangSwitcher } from "./LangSwitcher"; +import { Definition } from "@site/src/components/Definition"; import Admonition from "@theme/Admonition"; import type { MDXComponentsObject } from "@theme/MDXComponents"; import MDXA from "@theme/MDXComponents/A"; @@ -16,7 +13,10 @@ import MDXLi from "@theme/MDXComponents/Li"; import MDXPre from "@theme/MDXComponents/Pre"; import MDXUl from "@theme/MDXComponents/Ul"; import Mermaid from "@theme/Mermaid"; +import TabItem from "@theme/TabItem"; +import Tabs from "@theme/Tabs"; import React, { type ComponentProps } from "react"; +import { LangSwitcher } from "./LangSwitcher"; const MDXComponents: MDXComponentsObject = { Head, From e0545fd215f8f38d96140b9f8464db2e678cdc48 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 12:06:15 -0400 Subject: [PATCH 21/54] Add switcher example, default filename --- docs/agent-sdks/index.mdx | 69 +++++++++++++++++----- src/components/CodeBlockWithInfo/index.tsx | 36 +++++------ src/components/LangSwitcher/LangTab.tsx | 7 ++- src/components/LangSwitcher/index.tsx | 3 +- src/theme/MDXComponents/index.tsx | 2 +- 5 files changed, 81 insertions(+), 36 deletions(-) diff --git a/docs/agent-sdks/index.mdx b/docs/agent-sdks/index.mdx index 0f30c2090c..978ff09713 100644 --- a/docs/agent-sdks/index.mdx +++ b/docs/agent-sdks/index.mdx @@ -23,20 +23,61 @@ ngrok's cloud service just as if you opened a socket to listen on a port. ## Example Usage - - - - - - - - - - - - - - + +```go +import ( + "context" + "net" + + "golang.ngrok.com/ngrok/v2" +) + +func ngrokListener(ctx context.Context) (net.Listener, error) { + return ngrok.Listen(ctx) +} +``` + +```jsx +const ngrok = require("@ngrok/ngrok"); + +(async function () { + const listener = await ngrok.forward({ + addr: 8080, + authtoken_from_env: true, + }); + + console.log(`Ingress established at: ${listener.url()}`); +})(); +``` +```python +import ngrok + +listener = ngrok.forward("localhost:8080", authtoken_from_env=True) + +print(f"Ingress established at: {listener.url()}"); +``` + +```rust +use ngrok::prelude::*; + +async fn listen_ngrok() -> anyhow::Result { + let sess = ngrok::Session::builder() + .authtoken_from_env() + .connect() + .await?; + + let tun = sess + .http_endpoint() + .listen() + .await?; + + println!("Listening on URL: {:?}", tun.url()); + + Ok(tun) +} +``` + + ## Supported Languages diff --git a/src/components/CodeBlockWithInfo/index.tsx b/src/components/CodeBlockWithInfo/index.tsx index f0e7d83e77..be2ea5fa36 100644 --- a/src/components/CodeBlockWithInfo/index.tsx +++ b/src/components/CodeBlockWithInfo/index.tsx @@ -46,30 +46,30 @@ export function CodeBlockWithInfo({ content && content.split("\n").length > collapseLineNumber; + const finalTitle = meta?.title || "Example code"; + return (
- {meta?.title && ( -
- <> - {meta?.mode ? ( - +
+ <> + {meta?.mode ? ( + + ) : ( + + )} + + {meta?.titleLink ? ( + + {finalTitle} + ) : ( - + {finalTitle} )} - - {meta?.titleLink ? ( - - {meta.title} - - ) : ( - {meta?.title} - )} - - -
- )} + + +
{headerContent} {info && }
diff --git a/src/components/LangSwitcher/LangTab.tsx b/src/components/LangSwitcher/LangTab.tsx index 16d5e952db..a64f964d20 100644 --- a/src/components/LangSwitcher/LangTab.tsx +++ b/src/components/LangSwitcher/LangTab.tsx @@ -1,4 +1,7 @@ import { Button } from "@ngrok/mantle/button"; +import capitalize from "capitalize"; + +const langsToCapitalize = ["yaml", "json"]; export function LangTab({ tabText, @@ -20,7 +23,9 @@ export function LangTab({ appearance="ghost" className={className} > - {tabText} + {langsToCapitalize.includes(tabText) + ? tabText.toUpperCase() + : capitalize(tabText)} ); } diff --git a/src/components/LangSwitcher/index.tsx b/src/components/LangSwitcher/index.tsx index 974fee0474..59fef648a9 100644 --- a/src/components/LangSwitcher/index.tsx +++ b/src/components/LangSwitcher/index.tsx @@ -1,5 +1,4 @@ import BrowserOnly from "@docusaurus/BrowserOnly"; -import capitalize from "capitalize"; import clsx from "clsx"; import { useContext } from "react"; import { CodeBlockWithInfo } from "../CodeBlockWithInfo"; @@ -67,7 +66,7 @@ export function LangSwitcher({ children, className, ...props }: any) { ? "bg-neutral-500/10 text-neutral-800" : "text-neutral-500", )} - tabText={child?.meta.tabName || capitalize(child?.language)} + tabText={child?.meta.tabName || child?.language} /> ); })} diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 92840a1e7c..dbcb13a512 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -4,7 +4,7 @@ import TabItem from "@theme/TabItem"; import Tabs from "@theme/Tabs"; import ConfigExample from "@site/src/components/ConfigExample"; import { YouTubeEmbed } from "@components/youtube-embed"; -import { LangSwitcher } from "./LangSwitcher"; +import { LangSwitcher } from "@components/LangSwitcher"; import Admonition from "@theme/Admonition"; import type { MDXComponentsObject } from "@theme/MDXComponents"; import MDXA from "@theme/MDXComponents/A"; From 512d6160be73f9751cd22a7a15cab518e52b98c5 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 12:07:33 -0400 Subject: [PATCH 22/54] Update index.tsx --- src/theme/MDXComponents/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 7a3bf6c47b..8db81d42cd 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,4 +1,3 @@ -import { YouTubeEmbed } from "@components/youtube-embed"; import Head from "@docusaurus/Head"; import ConfigExample from "@site/src/components/ConfigExample"; import { YouTubeEmbed } from "@components/youtube-embed"; @@ -17,7 +16,6 @@ import Mermaid from "@theme/Mermaid"; import TabItem from "@theme/TabItem"; import Tabs from "@theme/Tabs"; import React, { type ComponentProps } from "react"; -import { LangSwitcher } from "./LangSwitcher"; const MDXComponents: MDXComponentsObject = { Head, From 7870978291a6b724e24c74e05b4adb8013c8316f Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 16:08:22 +0000 Subject: [PATCH 23/54] ci: apply automated fixes --- docs/agent-sdks/index.mdx | 13 ++++++++----- src/theme/MDXComponents/index.tsx | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/agent-sdks/index.mdx b/docs/agent-sdks/index.mdx index 978ff09713..2c9925914c 100644 --- a/docs/agent-sdks/index.mdx +++ b/docs/agent-sdks/index.mdx @@ -29,13 +29,15 @@ import ( "context" "net" - "golang.ngrok.com/ngrok/v2" + "golang.ngrok.com/ngrok/v2" + ) func ngrokListener(ctx context.Context) (net.Listener, error) { - return ngrok.Listen(ctx) +return ngrok.Listen(ctx) } -``` + +```` ```jsx const ngrok = require("@ngrok/ngrok"); @@ -48,7 +50,8 @@ const ngrok = require("@ngrok/ngrok"); console.log(`Ingress established at: ${listener.url()}`); })(); -``` +```` + ```python import ngrok @@ -76,8 +79,8 @@ async fn listen_ngrok() -> anyhow::Result { Ok(tun) } ``` - + ## Supported Languages diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 8db81d42cd..2a35e5b628 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,7 +1,7 @@ +import { LangSwitcher } from "@components/LangSwitcher"; +import { YouTubeEmbed } from "@components/youtube-embed"; import Head from "@docusaurus/Head"; import ConfigExample from "@site/src/components/ConfigExample"; -import { YouTubeEmbed } from "@components/youtube-embed"; -import { LangSwitcher } from "@components/LangSwitcher"; import Admonition from "@theme/Admonition"; import type { MDXComponentsObject } from "@theme/MDXComponents"; import MDXA from "@theme/MDXComponents/A"; From 43eccc9135c313bc4bdb0471e0441bbf3e79d3de Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 12:53:40 -0400 Subject: [PATCH 24/54] Fix the definition import --- src/theme/MDXComponents/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 2a35e5b628..58b28f014b 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,5 +1,6 @@ import { LangSwitcher } from "@components/LangSwitcher"; import { YouTubeEmbed } from "@components/youtube-embed"; +import { Definition } from "@site/src/components/Definition"; import Head from "@docusaurus/Head"; import ConfigExample from "@site/src/components/ConfigExample"; import Admonition from "@theme/Admonition"; From b8e085471a879f4a992350fd7615d4a2b62baf78 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 16:54:33 +0000 Subject: [PATCH 25/54] ci: apply automated fixes --- src/theme/MDXComponents/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/theme/MDXComponents/index.tsx b/src/theme/MDXComponents/index.tsx index 58b28f014b..a829e4b7ba 100644 --- a/src/theme/MDXComponents/index.tsx +++ b/src/theme/MDXComponents/index.tsx @@ -1,8 +1,8 @@ import { LangSwitcher } from "@components/LangSwitcher"; import { YouTubeEmbed } from "@components/youtube-embed"; -import { Definition } from "@site/src/components/Definition"; import Head from "@docusaurus/Head"; import ConfigExample from "@site/src/components/ConfigExample"; +import { Definition } from "@site/src/components/Definition"; import Admonition from "@theme/Admonition"; import type { MDXComponentsObject } from "@theme/MDXComponents"; import MDXA from "@theme/MDXComponents/A"; From 9848cadcf3f333b7a0634ce591da0da7b7940a64 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 13:02:04 -0400 Subject: [PATCH 26/54] Fix unimported item --- src/theme/CodeBlock/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/theme/CodeBlock/index.tsx b/src/theme/CodeBlock/index.tsx index b223b7004a..37d1890797 100644 --- a/src/theme/CodeBlock/index.tsx +++ b/src/theme/CodeBlock/index.tsx @@ -1,5 +1,4 @@ import BrowserOnly from "@docusaurus/BrowserOnly"; -import { cx } from "@ngrok/mantle/cx"; import type { ComponentProps } from "react"; import DocsCodeBlock, { CodeBlockFallback } from "../../components/code-block"; From ba56eff10ef0e1234293b00863dd751220d56dea Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 13:23:56 -0400 Subject: [PATCH 27/54] Lang swapping --- docs/agent-sdks/index.mdx | 6 +++--- src/components/CodeBlockWithInfo/index.tsx | 6 +++--- src/components/LangSwitcher/LangTab.tsx | 14 ++++++++++---- src/components/code-block.tsx | 13 +++++-------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/docs/agent-sdks/index.mdx b/docs/agent-sdks/index.mdx index 2c9925914c..71d2920ccc 100644 --- a/docs/agent-sdks/index.mdx +++ b/docs/agent-sdks/index.mdx @@ -34,12 +34,12 @@ import ( ) func ngrokListener(ctx context.Context) (net.Listener, error) { -return ngrok.Listen(ctx) + return ngrok.Listen(ctx) } -```` +``` -```jsx +```javascript const ngrok = require("@ngrok/ngrok"); (async function () { diff --git a/src/components/CodeBlockWithInfo/index.tsx b/src/components/CodeBlockWithInfo/index.tsx index be2ea5fa36..045a92a237 100644 --- a/src/components/CodeBlockWithInfo/index.tsx +++ b/src/components/CodeBlockWithInfo/index.tsx @@ -46,7 +46,7 @@ export function CodeBlockWithInfo({ content && content.split("\n").length > collapseLineNumber; - const finalTitle = meta?.title || "Example code"; + const finalTitle = meta?.title || "Example"; return (
@@ -59,7 +59,7 @@ export function CodeBlockWithInfo({ ) : ( )} - + {meta?.titleLink ? ( {finalTitle} @@ -71,7 +71,7 @@ export function CodeBlockWithInfo({
{headerContent} - {info && } + {info && } {!meta?.disableCopy && } diff --git a/src/components/LangSwitcher/LangTab.tsx b/src/components/LangSwitcher/LangTab.tsx index a64f964d20..5771841de1 100644 --- a/src/components/LangSwitcher/LangTab.tsx +++ b/src/components/LangSwitcher/LangTab.tsx @@ -1,7 +1,11 @@ import { Button } from "@ngrok/mantle/button"; import capitalize from "capitalize"; -const langsToCapitalize = ["yaml", "json"]; +const langsToCapitalize = ["yaml", "json", "txt", "sh", "jsx", "tsx"]; +const langsToSwap = [ + { name: "js", swapName: "javascript" }, + { name: "ts", swapName: "typescript" }, +]; export function LangTab({ tabText, @@ -14,6 +18,8 @@ export function LangTab({ disabled?: boolean; onClick?: () => void; }) { + const finalTabText = + langsToSwap.find((lang) => lang.name === tabText)?.swapName || tabText; return ( ); } diff --git a/src/components/code-block.tsx b/src/components/code-block.tsx index 83454e234f..bc528f2ee9 100644 --- a/src/components/code-block.tsx +++ b/src/components/code-block.tsx @@ -83,14 +83,11 @@ function DocsCodeBlock({ meta={meta} className={`mb-4 ${className}`} headerContent={ - <> - {meta.title && {meta.title}} - - + } info={getLanguageInfo(language)} codeBlockProps={props} From 29cae9e9cf5980c8cfb0f39a94e9aea76ce97c93 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 20 Jun 2025 17:24:45 +0000 Subject: [PATCH 28/54] ci: apply automated fixes --- docs/agent-sdks/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/agent-sdks/index.mdx b/docs/agent-sdks/index.mdx index 71d2920ccc..8c7b16c486 100644 --- a/docs/agent-sdks/index.mdx +++ b/docs/agent-sdks/index.mdx @@ -34,10 +34,10 @@ import ( ) func ngrokListener(ctx context.Context) (net.Listener, error) { - return ngrok.Listen(ctx) +return ngrok.Listen(ctx) } -``` +```` ```javascript const ngrok = require("@ngrok/ngrok"); From dcfae7dc904af3224e7fc332bcd34213f6810871 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 13:30:49 -0400 Subject: [PATCH 29/54] Update code-block.tsx --- src/components/code-block.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/code-block.tsx b/src/components/code-block.tsx index bc528f2ee9..0d20dc50b7 100644 --- a/src/components/code-block.tsx +++ b/src/components/code-block.tsx @@ -5,7 +5,6 @@ import type { } from "@ngrok/mantle/code-block"; import { CodeBlock, parseLanguage } from "@ngrok/mantle/code-block"; import type { WithStyleProps } from "@ngrok/mantle/types"; -import capitalize from "capitalize"; import type { ComponentProps, ReactNode } from "react"; import { CodeBlockWithInfo } from "./CodeBlockWithInfo"; import { LangTab } from "./LangSwitcher/LangTab"; From 5f7944fcd11361e9655566347cb8dcb7ce84d667 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Fri, 20 Jun 2025 15:09:43 -0400 Subject: [PATCH 30/54] Ready to merge --- docs/agent-sdks/index.mdx | 10 +++--- src/components/CodeBlockWithInfo/index.tsx | 36 +++++++++++----------- src/components/LangSwitcher/SdkButton.tsx | 5 ++- src/components/LangSwitcher/data.ts | 30 ++++++++++-------- src/components/code-block.tsx | 12 +++++--- 5 files changed, 50 insertions(+), 43 deletions(-) diff --git a/docs/agent-sdks/index.mdx b/docs/agent-sdks/index.mdx index 8c7b16c486..de45f6fe85 100644 --- a/docs/agent-sdks/index.mdx +++ b/docs/agent-sdks/index.mdx @@ -28,16 +28,14 @@ ngrok's cloud service just as if you opened a socket to listen on a port. import ( "context" "net" - - "golang.ngrok.com/ngrok/v2" - + "golang.ngrok.com/ngrok/v2" ) func ngrokListener(ctx context.Context) (net.Listener, error) { -return ngrok.Listen(ctx) + return ngrok.Listen(ctx) } -```` +``` ```javascript const ngrok = require("@ngrok/ngrok"); @@ -50,7 +48,7 @@ const ngrok = require("@ngrok/ngrok"); console.log(`Ingress established at: ${listener.url()}`); })(); -```` +``` ```python import ngrok diff --git a/src/components/CodeBlockWithInfo/index.tsx b/src/components/CodeBlockWithInfo/index.tsx index 045a92a237..b869cc29cb 100644 --- a/src/components/CodeBlockWithInfo/index.tsx +++ b/src/components/CodeBlockWithInfo/index.tsx @@ -46,30 +46,30 @@ export function CodeBlockWithInfo({ content && content.split("\n").length > collapseLineNumber; - const finalTitle = meta?.title || "Example"; - return (
-
- <> - {meta?.mode ? ( - - ) : ( - - )} - - {meta?.titleLink ? ( - - {finalTitle} - + {meta?.title && ( +
+ <> + {meta?.mode ? ( + ) : ( - {finalTitle} + )} - - -
+ + {meta?.titleLink ? ( + + {meta.title} + + ) : ( + {meta.title} + )} + + +
+ )} {headerContent} {info && } diff --git a/src/components/LangSwitcher/SdkButton.tsx b/src/components/LangSwitcher/SdkButton.tsx index ef34fd098c..228c843d20 100644 --- a/src/components/LangSwitcher/SdkButton.tsx +++ b/src/components/LangSwitcher/SdkButton.tsx @@ -7,6 +7,9 @@ export function SdkButton({ data, className, }: { data: LanguageInfo; className?: string }) { + if (!data.links || data.links.length === 0) { + return null; + } const anchoredLinks = data.links.map((link) => { return ( @@ -21,7 +24,7 @@ export function SdkButton({ if (index === 0) { return [prev, curr]; } - if (index === data.links.length - 1) { + if (data?.links && index === data.links.length - 1) { return [prev, ", and ", curr]; } return [prev, ", ", curr]; diff --git a/src/components/LangSwitcher/data.ts b/src/components/LangSwitcher/data.ts index 44621c7e6c..0f74ff97a0 100644 --- a/src/components/LangSwitcher/data.ts +++ b/src/components/LangSwitcher/data.ts @@ -2,7 +2,7 @@ export type LanguageInfo = { name: string; allNames?: string[]; displayName: string; - links: string[]; + links?: string[]; }; export const languageInfo: LanguageInfo[] = [ @@ -38,18 +38,22 @@ export const languageInfo: LanguageInfo[] = [ links: ["https://ngrok.github.io/ngrok-javascript/"], allNames: ["typescript", "ts", "tsx"], }, -]; - -export type CustomLanguage = { - name: string; - // The language whose syntax should be used. - // For example, a "ssh" language could use "bash" syntax. - syntaxLanguage: string; -}; - -export const customLanguages: CustomLanguage[] = [ { - name: "ssh", - syntaxLanguage: "bash", + name: "bash", + displayName: "Bash", + allNames: ["sh", "bash", "shell", "http"], + }, + { + name: "yaml", + displayName: "YAML", + allNames: ["Yaml", "yaml", "yml"], + }, + { + name: "json", + displayName: "JSON", + }, + { + name: "txt", + displayName: "TXT", }, ]; diff --git a/src/components/code-block.tsx b/src/components/code-block.tsx index 0d20dc50b7..0f97aeb9e1 100644 --- a/src/components/code-block.tsx +++ b/src/components/code-block.tsx @@ -9,6 +9,7 @@ import type { ComponentProps, ReactNode } from "react"; import { CodeBlockWithInfo } from "./CodeBlockWithInfo"; import { LangTab } from "./LangSwitcher/LangTab"; import { getLanguageInfo, getMetaData } from "./LangSwitcher/utils"; +import { languageInfo } from "./LangSwitcher/data"; type WithIndentation = Pick< ComponentProps, @@ -64,16 +65,17 @@ function DocsCodeBlock({ const langInClassName = langMatchesInClassName ? langMatchesInClassName[0]?.split("-")[1] : ""; - const language = _language || parseLanguage(langInClassName); + const langToFind = langInClassName || parseLanguage(langInClassName); + + const language = + languageInfo.find( + (lang) => lang.name === langToFind || lang.allNames?.includes(langToFind), + )?.name || langToFind; const meta = getMetaData( metastring ? `${className} ${metastring}` : className, ); - if (className?.includes("mb")) { - console.log("Classname", className); - } - return ( Date: Fri, 20 Jun 2025 19:10:34 +0000 Subject: [PATCH 31/54] ci: apply automated fixes --- docs/agent-sdks/index.mdx | 6 +++--- src/components/code-block.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/agent-sdks/index.mdx b/docs/agent-sdks/index.mdx index de45f6fe85..0cbabc958c 100644 --- a/docs/agent-sdks/index.mdx +++ b/docs/agent-sdks/index.mdx @@ -32,10 +32,10 @@ import ( ) func ngrokListener(ctx context.Context) (net.Listener, error) { - return ngrok.Listen(ctx) +return ngrok.Listen(ctx) } -``` +```` ```javascript const ngrok = require("@ngrok/ngrok"); @@ -48,7 +48,7 @@ const ngrok = require("@ngrok/ngrok"); console.log(`Ingress established at: ${listener.url()}`); })(); -``` +```` ```python import ngrok diff --git a/src/components/code-block.tsx b/src/components/code-block.tsx index 0f97aeb9e1..9470e0a6c3 100644 --- a/src/components/code-block.tsx +++ b/src/components/code-block.tsx @@ -8,8 +8,8 @@ import type { WithStyleProps } from "@ngrok/mantle/types"; import type { ComponentProps, ReactNode } from "react"; import { CodeBlockWithInfo } from "./CodeBlockWithInfo"; import { LangTab } from "./LangSwitcher/LangTab"; -import { getLanguageInfo, getMetaData } from "./LangSwitcher/utils"; import { languageInfo } from "./LangSwitcher/data"; +import { getLanguageInfo, getMetaData } from "./LangSwitcher/utils"; type WithIndentation = Pick< ComponentProps, From 513ef77d25421cdc7b92baec1f8362f412b93431 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 10:35:00 -0400 Subject: [PATCH 32/54] Protect pages where the term is the subject --- src/components/Definition/index.tsx | 11 +++++++++++ src/plugins/definition-wrapper.js | 1 + 2 files changed, 12 insertions(+) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index c875045390..e736c7c063 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -20,6 +20,7 @@ type DefinitionProps = { children: React.ReactNode; meaning?: string; link?: string; + dontShowIfInPageURL?: boolean; className?: string; }; @@ -28,6 +29,7 @@ export function Definition({ meaning, link, className, + dontShowIfInPageURL, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); const linkType = link?.startsWith("http") @@ -44,6 +46,15 @@ export function Definition({ ); const { pathname } = useLocation(); + + if(dontShowIfInPageURL && pathname) { + // If the term is in the page URL, don't show the definition. + // This prevents showing definitions for terms on pages that + // already explain them. + if (pathname.includes(children.toString())) { + return <>{children}; + } + } // Don't get the match if the meaning or link is provided const match = diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 7e2978c05b..fb98ea3500 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -121,6 +121,7 @@ module.exports = function remarkWordWrapper(stuff) { meaning: matchingTerm.meaning, link: matchingTerm.link, className: styles, + dontShowIfInPageURL: true, }, children: [ { From 88f7f65366dfa12f308282bfc1ebaa335bb22f25 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 10:49:34 -0400 Subject: [PATCH 33/54] Add extra definitions --- src/components/Definition/data.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index beef2dcef7..fd54296445 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -18,10 +18,29 @@ export const terms: Term[] = [ pluralEnding: "s", }, { - titles: ["SCIM", "SCIM provisioning"], + titles: ["IP CIDR", "CIDR"], meaning: - "SSO SCIM Provisioning refers to the combination of two identity management technologies: Single Sign-On (SSO) and System for Cross-domain Identity Management (SCIM). Together, they automate user account creation, updates, and removal across different systems.", - link: "https://en.wikipedia.org/wiki/System_for_Cross-domain_Identity_Management", + "Classless Inter-Domain Routing is a method used to allocate IP addresses more efficiently and route IP packets more flexibly than the older class-based system.", + link: "https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing", + pluralEnding: "s", + }, + { + titles: ["shadow IT"], + meaning: + "Shadow IT refers IT systems, software, and cloud services used by individuals within an organization without the IT department's knowledge or approval", + link: "https://en.wikipedia.org/wiki/Shadow_IT", + }, + { + titles: ["OpenID Connect", "OIDC"], + meaning: + "OpenID Connect (OIDC) is an authentication protocol that enables third-party applications to confirm a user's identity and access basic profile details through a single sign-on (SSO) process.", + link: "https://en.wikipedia.org/wiki/OpenID", + }, + { + titles: ["Let’s Encrypt", "Let's Encrypt", "LetsEncrypt", "Lets encrypt"], + meaning: + "Let's Encrypt is a free, automated, and open certificate authority (CA) that provides digital certificates to enable HTTPS (SSL/TLS) for websites.", + link: "https://letsencrypt.org/about/", }, { titles: ["JIT provisioning"], From 1f0a112f0ca9f09d8351c2d12de012529b20ccd8 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 10:59:31 -0400 Subject: [PATCH 34/54] Improve how we find definition in the page URL --- src/components/Definition/index.tsx | 39 ++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index e736c7c063..28d64aeeef 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -24,6 +24,25 @@ type DefinitionProps = { className?: string; }; +function foundDefinitionInUrl( + pathname: string, + children: React.ReactNode, + titles: string[] | undefined, +): boolean { + if (!children) return false; + if (pathname.includes(children.toString())) { + return true; + } + if (titles) { + for (const title of titles) { + if (pathname.includes(title)) { + return true; + } + } + } + return false; +} + export function Definition({ children, meaning, @@ -46,15 +65,6 @@ export function Definition({ ); const { pathname } = useLocation(); - - if(dontShowIfInPageURL && pathname) { - // If the term is in the page URL, don't show the definition. - // This prevents showing definitions for terms on pages that - // already explain them. - if (pathname.includes(children.toString())) { - return <>{children}; - } - } // Don't get the match if the meaning or link is provided const match = @@ -72,6 +82,17 @@ export function Definition({ : link || match?.link, }; + // If this flag is set to true, don't show the definition component + // on a page that includes the term in the URL. This prevents adding + // the definition component to pages that already explain the term. + // For example if we have a page at /docs/ingress, we don't + // want to show the definition component for "ingress" on that page. + if (dontShowIfInPageURL) { + if (foundDefinitionInUrl(pathname, children, match?.titles)) { + return <>{children}; + } + } + const iconSize = 4; return ( From 7d5026e815545f5f458a3982a7340ed354d53512 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 11:51:32 -0400 Subject: [PATCH 35/54] Fix it again --- src/components/Definition/index.tsx | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 28d64aeeef..8de9685f49 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -15,6 +15,7 @@ import { import clsx from "clsx"; import type React from "react"; import { terms } from "./data"; +import path from "node:path"; type DefinitionProps = { children: React.ReactNode; @@ -24,25 +25,6 @@ type DefinitionProps = { className?: string; }; -function foundDefinitionInUrl( - pathname: string, - children: React.ReactNode, - titles: string[] | undefined, -): boolean { - if (!children) return false; - if (pathname.includes(children.toString())) { - return true; - } - if (titles) { - for (const title of titles) { - if (pathname.includes(title)) { - return true; - } - } - } - return false; -} - export function Definition({ children, meaning, @@ -88,7 +70,10 @@ export function Definition({ // For example if we have a page at /docs/ingress, we don't // want to show the definition component for "ingress" on that page. if (dontShowIfInPageURL) { - if (foundDefinitionInUrl(pathname, children, match?.titles)) { + if ( + pathname.includes(children.toString().toLowerCase()) || + pathname.includes(meaning.toLowerCase()) + ) { return <>{children}; } } From 33d271b9c18bc91dcf268bd577fc37ea8e73ba42 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 15:52:31 +0000 Subject: [PATCH 36/54] ci: apply automated fixes --- src/components/Definition/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 8de9685f49..731e9030ca 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -1,3 +1,4 @@ +import path from "node:path"; import Link from "@docusaurus/Link"; import { useLocation } from "@docusaurus/router"; import { Button } from "@ngrok/mantle/button"; @@ -15,7 +16,6 @@ import { import clsx from "clsx"; import type React from "react"; import { terms } from "./data"; -import path from "node:path"; type DefinitionProps = { children: React.ReactNode; From 50961c408507b62a06474e2c10a16e73d97a4dee Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 11:59:44 -0400 Subject: [PATCH 37/54] Fix type issues --- src/components/Definition/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 8de9685f49..4bf82bd98c 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -15,7 +15,6 @@ import { import clsx from "clsx"; import type React from "react"; import { terms } from "./data"; -import path from "node:path"; type DefinitionProps = { children: React.ReactNode; @@ -72,7 +71,7 @@ export function Definition({ if (dontShowIfInPageURL) { if ( pathname.includes(children.toString().toLowerCase()) || - pathname.includes(meaning.toLowerCase()) + (meaning && pathname.includes(meaning.toLowerCase())) ) { return <>{children}; } From 2d62ca7be2507ba541d6f7483dfec626db626c09 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 12:15:55 -0400 Subject: [PATCH 38/54] Remove dontshowifinpageurl functionality --- src/components/Definition/index.tsx | 16 ---------------- src/plugins/definition-wrapper.js | 1 - 2 files changed, 17 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index f080aae581..f8cd479ee5 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -21,7 +21,6 @@ type DefinitionProps = { children: React.ReactNode; meaning?: string; link?: string; - dontShowIfInPageURL?: boolean; className?: string; }; @@ -30,7 +29,6 @@ export function Definition({ meaning, link, className, - dontShowIfInPageURL, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); const linkType = link?.startsWith("http") @@ -64,20 +62,6 @@ export function Definition({ : link || match?.link, }; - // If this flag is set to true, don't show the definition component - // on a page that includes the term in the URL. This prevents adding - // the definition component to pages that already explain the term. - // For example if we have a page at /docs/ingress, we don't - // want to show the definition component for "ingress" on that page. - if (dontShowIfInPageURL) { - if ( - pathname.includes(children.toString().toLowerCase()) || - (meaning && pathname.includes(meaning.toLowerCase())) - ) { - return <>{children}; - } - } - const iconSize = 4; return ( diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index fb98ea3500..7e2978c05b 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -121,7 +121,6 @@ module.exports = function remarkWordWrapper(stuff) { meaning: matchingTerm.meaning, link: matchingTerm.link, className: styles, - dontShowIfInPageURL: true, }, children: [ { From a3e3dfb9d973f55ed245281a162d455ac3855fc0 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Mon, 23 Jun 2025 12:16:12 -0400 Subject: [PATCH 39/54] Remove import --- src/components/Definition/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index f8cd479ee5..c875045390 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -1,4 +1,3 @@ -import path from "node:path"; import Link from "@docusaurus/Link"; import { useLocation } from "@docusaurus/router"; import { Button } from "@ngrok/mantle/button"; From 320d1aaaab72b6f52d9ece3ae1f56d2c0ca12f88 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Tue, 24 Jun 2025 10:33:16 -0400 Subject: [PATCH 40/54] Re-adding the hide-if-in-path functionality. Feels necessary to call this complete --- src/components/Definition/data.ts | 17 +++++++++++++++++ src/components/Definition/index.tsx | 20 +++++++++++++++++++- src/plugins/definition-wrapper.js | 3 ++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index fd54296445..76a9f91a86 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -82,8 +82,22 @@ export const terms: Term[] = [ meaning: "v2 is shorthand for the second major version of the ngrok Agent.", link: "/docs/agent/config/v2", }, + { + titles: ["Traffic Policy", "Traffic Policies"], + meaning: + "Traffic Policy is a configuration language that offers you the flexibility to filter, match, manage and orchestrate traffic to your endpoints. For example, you can add authentication, send custom response, rate limit traffic, and more.", + link: "/docs/traffic-policy/", + }, + { + titles: ["Endpoint pool", "Endpoint Pooling"], + meaning: + 'When your create two endpoints with the same URL (and binding), those endpoints automatically form a "pool" and share incoming traffic.', + link: "/docs/universal-gateway/endpoint-pooling/", + pluralEnding: "s", + }, { titles: ["OWASP"], + caseSensitive: true, meaning: "OWASP: The Open Web Application Security Project. This non-profit organization is dedicated to improving software security through providing resources, tools, and community support.", link: "https://owasp.org/about/", @@ -109,6 +123,7 @@ export const terms: Term[] = [ }, { titles: ["CRD", "Custom Resource Definition"], + caseSensitive: true, meaning: "CustomResourceDefinitions allow users to extend the Kubernetes API by defining their own resource types.", link: "https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/", @@ -116,12 +131,14 @@ export const terms: Term[] = [ }, { titles: ["ALPN"], + caseSensitive: true, link: "https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation", meaning: "ALPN (Application-Layer Protocol Negotiation) allows a client and server to negotiate which application protocol (like HTTP/2 or HTTP/1.1) to use over a secure connection during the TLS handshake.", }, { titles: ["SNI"], + caseSensitive: true, link: "https://en.wikipedia.org/wiki/Server_Name_Indication", meaning: "SNI (Server Name Indication) is a TLS extension that allows a client to specify the hostname it is trying to connect to during the TLS handshake, enabling servers to present the correct SSL/TLS certificate for that hostname.", diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index c875045390..393c0ffc4c 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -14,13 +14,15 @@ import { } from "@phosphor-icons/react"; import clsx from "clsx"; import type React from "react"; -import { terms } from "./data"; +import { terms, type Term } from "./data"; type DefinitionProps = { children: React.ReactNode; meaning?: string; link?: string; className?: string; + term?: Term; + hideIfInPath?: boolean; }; export function Definition({ @@ -28,6 +30,8 @@ export function Definition({ meaning, link, className, + term, + hideIfInPath, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); const linkType = link?.startsWith("http") @@ -63,6 +67,20 @@ export function Definition({ const iconSize = 4; + if (hideIfInPath) { + // If the term is in the current URL path, don't show + // the definition. This prevents showing definitions + // for terms that are already explained on the page. + if ( + term?.titles.some((title) => + pathname.includes(title.split(" ").join("-").toLowerCase()), + ) || + term?.link?.includes(pathname) + ) { + return <>{children}; + } + } + return ( diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 7e2978c05b..4304569fbe 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -118,7 +118,8 @@ module.exports = function remarkWordWrapper(stuff) { type: "element", tagName: "Definition", properties: { - meaning: matchingTerm.meaning, + term: matchingTerm, + hideIfInPath: true, link: matchingTerm.link, className: styles, }, From beae97a27d2df6323590e429626ebdc01c1f942f Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 24 Jun 2025 14:34:07 +0000 Subject: [PATCH 41/54] ci: apply automated fixes --- src/components/Definition/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 393c0ffc4c..a2ab9eb562 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -14,7 +14,7 @@ import { } from "@phosphor-icons/react"; import clsx from "clsx"; import type React from "react"; -import { terms, type Term } from "./data"; +import { type Term, terms } from "./data"; type DefinitionProps = { children: React.ReactNode; From dc6e50efbed51d4573f0880843adac1589e72377 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Tue, 24 Jun 2025 12:16:22 -0400 Subject: [PATCH 42/54] Okay enough; let's ship --- src/components/Definition/data.ts | 1 + src/components/Definition/index.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 76a9f91a86..cb47d2f7d2 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -52,6 +52,7 @@ export const terms: Term[] = [ titles: ["K8"], meaning: "K8s is an industry-standard abbreviation for Kubernetes.", pluralEnding: "s", + link: "https://kubernetes.io/docs/concepts/overview/", }, { titles: ["Ingress"], diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index a2ab9eb562..d3d36468cd 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -71,9 +71,10 @@ export function Definition({ // If the term is in the current URL path, don't show // the definition. This prevents showing definitions // for terms that are already explained on the page. + const pathWithoutHash = pathname.split("#")[0]; if ( term?.titles.some((title) => - pathname.includes(title.split(" ").join("-").toLowerCase()), + pathWithoutHash?.includes(title.split(" ").join("-").toLowerCase()), ) || term?.link?.includes(pathname) ) { @@ -93,7 +94,6 @@ export function Definition({ > <> {children} - From 2c4912c6e63d50592003797ed2a4ffa5f3d029ba Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Tue, 24 Jun 2025 14:27:49 -0400 Subject: [PATCH 43/54] Okay it actually works --- src/components/Definition/index.tsx | 37 +++++++++++++---------------- src/plugins/definition-wrapper.js | 4 +++- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index d3d36468cd..cc00732355 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -21,7 +21,6 @@ type DefinitionProps = { meaning?: string; link?: string; className?: string; - term?: Term; hideIfInPath?: boolean; }; @@ -30,7 +29,6 @@ export function Definition({ meaning, link, className, - term, hideIfInPath, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); @@ -58,30 +56,29 @@ export function Definition({ meaning: meaning || match?.meaning, // If link is to the current page, don't use it. No need to // link to the same page. - link: !link - ? undefined - : pathname?.includes(link) - ? undefined - : link || match?.link, + link: link || match?.link, }; - const iconSize = 4; - - if (hideIfInPath) { - // If the term is in the current URL path, don't show - // the definition. This prevents showing definitions - // for terms that are already explained on the page. - const pathWithoutHash = pathname.split("#")[0]; - if ( - term?.titles.some((title) => - pathWithoutHash?.includes(title.split(" ").join("-").toLowerCase()), - ) || - term?.link?.includes(pathname) - ) { + if (data.link && hideIfInPath) { + console.log("here"); + const pathSegments = pathname.split("/"); + const lastPathSegment = pathSegments[pathSegments.length - 2]; + console.log("pathSegments", pathSegments); + console.log("lastPathSegment", lastPathSegment); + if (lastPathSegment && data.link.includes(lastPathSegment)) { + // If the link is in the current path, don't render + // the definition component return <>{children}; } } + if (!data.link && hideIfInPath) { + // If there's no link and we're hiding if in path, don't render + return <>{children}; + } + + const iconSize = 4; + return ( diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 4304569fbe..792f72e7c9 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -1,3 +1,5 @@ +import { title } from "process"; + const { visit } = require("unist-util-visit"); const { terms } = require("../components/Definition/data"); @@ -118,7 +120,7 @@ module.exports = function remarkWordWrapper(stuff) { type: "element", tagName: "Definition", properties: { - term: matchingTerm, + meaning: matchingTerm.meaning, hideIfInPath: true, link: matchingTerm.link, className: styles, From 310f42a8d20408268900e2e5065d0ef924b337df Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Tue, 24 Jun 2025 14:42:41 -0400 Subject: [PATCH 44/54] Protect against buttons and spans --- src/components/Definition/index.tsx | 14 +++++--------- src/components/LangSwitcher/data.ts | 2 +- src/plugins/definition-wrapper.js | 2 ++ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index cc00732355..b2bf2f0b28 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -21,6 +21,9 @@ type DefinitionProps = { meaning?: string; link?: string; className?: string; + // If true, the definition will not be rendered if the last + // path segment matches the link. This is useful to avoid + // rendering definitions that link to the current page. hideIfInPath?: boolean; }; @@ -60,23 +63,16 @@ export function Definition({ }; if (data.link && hideIfInPath) { - console.log("here"); const pathSegments = pathname.split("/"); const lastPathSegment = pathSegments[pathSegments.length - 2]; - console.log("pathSegments", pathSegments); - console.log("lastPathSegment", lastPathSegment); if (lastPathSegment && data.link.includes(lastPathSegment)) { // If the link is in the current path, don't render - // the definition component + // the definition component. Prevents showing + // definitions that link to the current page. return <>{children}; } } - if (!data.link && hideIfInPath) { - // If there's no link and we're hiding if in path, don't render - return <>{children}; - } - const iconSize = 4; return ( diff --git a/src/components/LangSwitcher/data.ts b/src/components/LangSwitcher/data.ts index 0f74ff97a0..831e88c337 100644 --- a/src/components/LangSwitcher/data.ts +++ b/src/components/LangSwitcher/data.ts @@ -41,7 +41,7 @@ export const languageInfo: LanguageInfo[] = [ { name: "bash", displayName: "Bash", - allNames: ["sh", "bash", "shell", "http"], + allNames: ["sh", "bash", "shell", "http", "hcl"], }, { name: "yaml", diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 792f72e7c9..5a2d3574d8 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -26,6 +26,8 @@ function parentIsForbiddenTag(tagName) { "Definition", "code", "pre", + "button", + "span", ]; return forbiddenTags.includes(tagName); } From d25a684e7fd0ae056188146afc7f9e7135c5c03d Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Tue, 24 Jun 2025 14:57:53 -0400 Subject: [PATCH 45/54] Remove random import --- src/plugins/definition-wrapper.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index 5a2d3574d8..b816c38352 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -1,5 +1,3 @@ -import { title } from "process"; - const { visit } = require("unist-util-visit"); const { terms } = require("../components/Definition/data"); From 4fbb41ad2ca5178ff9d95ae158dd8cfbd4af9a73 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 25 Jun 2025 09:58:34 -0400 Subject: [PATCH 46/54] Fix broken pages --- src/components/Definition/data.ts | 2 +- src/components/LangSwitcher/data.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index cb47d2f7d2..c98f180cf7 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -123,7 +123,7 @@ export const terms: Term[] = [ pluralEnding: "s", }, { - titles: ["CRD", "Custom Resource Definition"], + titles: ["CRD"], caseSensitive: true, meaning: "CustomResourceDefinitions allow users to extend the Kubernetes API by defining their own resource types.", diff --git a/src/components/LangSwitcher/data.ts b/src/components/LangSwitcher/data.ts index 831e88c337..c59787df5e 100644 --- a/src/components/LangSwitcher/data.ts +++ b/src/components/LangSwitcher/data.ts @@ -41,7 +41,7 @@ export const languageInfo: LanguageInfo[] = [ { name: "bash", displayName: "Bash", - allNames: ["sh", "bash", "shell", "http", "hcl"], + allNames: ["sh", "bash", "shell", "http", "hcl", "toml", "cel", "curl"], }, { name: "yaml", From fba11ade2d017f93f62f7d44be6f66a3304aa762 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 25 Jun 2025 10:04:03 -0400 Subject: [PATCH 47/54] Add catch-all language --- src/components/LangSwitcher/data.ts | 9 +++++---- src/components/LangSwitcher/utils.ts | 11 ++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/LangSwitcher/data.ts b/src/components/LangSwitcher/data.ts index c59787df5e..12906a4419 100644 --- a/src/components/LangSwitcher/data.ts +++ b/src/components/LangSwitcher/data.ts @@ -6,6 +6,11 @@ export type LanguageInfo = { }; export const languageInfo: LanguageInfo[] = [ + { + // Leave this as the first item so it's the default + name: "txt", + displayName: "TXT", + }, { name: "go", displayName: "Go", @@ -52,8 +57,4 @@ export const languageInfo: LanguageInfo[] = [ name: "json", displayName: "JSON", }, - { - name: "txt", - displayName: "TXT", - }, ]; diff --git a/src/components/LangSwitcher/utils.ts b/src/components/LangSwitcher/utils.ts index 9f70f27c1f..3dc00550e1 100644 --- a/src/components/LangSwitcher/utils.ts +++ b/src/components/LangSwitcher/utils.ts @@ -89,10 +89,19 @@ export const getCodeBlocks = (children: ReactElement[]): CodeBlockData[] => { }; export const getLanguageInfo = (language: string) => { - return languageInfo.find( + const foundLang = languageInfo.find( (item) => item.name === language || item?.allNames?.some((alt) => alt === language), ); + + if (!foundLang) { + console.error("Language not valid for codeblocks:", language); + // If can't find it, return `txt` lang. This lang + // has no syntax highlighting, which will make it + // obvious something is wrong + return languageInfo[0]; + } + return foundLang; }; export function languagesAreSynonyms( From 9111f5dcdb38df3ecc8a4d09c9201e93e2359a7a Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 25 Jun 2025 10:23:02 -0400 Subject: [PATCH 48/54] Update data.ts --- src/components/Definition/data.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index c98f180cf7..3e3fa30efc 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -115,6 +115,26 @@ export const terms: Term[] = [ "TLS termination is the process of decrypting incoming TLS (Transport Layer Security) traffic at a server or load balancer before passing the unencrypted traffic to internal systems.", link: "/docs/universal-gateway/tls-termination/", }, + { + titles: ["TLS Certificate"], + pluralEnding: "s", + link: "https://en.wikipedia.org/wiki/Transport_Layer_Security", + meaning: + "A TLS certificate (or SSL certificate) is a digital certificate that ensure your connection to a website or server is securly encrypted.", + }, + { + titles: ["reverse proxy", "reverse proxies"], + link: "https://en.wikipedia.org/wiki/Reverse_proxy", + meaning: + "Reverse proxies are computer infrastructure, such as servers or cloud services, that intercept and then forward traffic to the upstream services. They are an extra security layer between public traffic and your internal services.", + }, + { + titles: ["WAF"], + link: "https://en.wikipedia.org/wiki/Web_application_firewall", + caseSensitive: true, + meaning: + "A web application firewall (WAF) is a type of reverse proxy that protects web services by filtering and monitoring HTTP traffic.", + }, { titles: ["Gateway API CRD", "Gateway API"], link: "https://gateway-api.sigs.k8s.io/guides/", From 995c9d8c03bf58c6883253bad8ca71f1278bdadd Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Wed, 25 Jun 2025 10:52:11 -0400 Subject: [PATCH 49/54] Remove unused import --- src/components/Definition/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index b2bf2f0b28..0890b25b56 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -14,7 +14,7 @@ import { } from "@phosphor-icons/react"; import clsx from "clsx"; import type React from "react"; -import { type Term, terms } from "./data"; +import { terms } from "./data"; type DefinitionProps = { children: React.ReactNode; From 2168d766c757a5cebf33f6433e7eea8914575691 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 26 Jun 2025 10:17:25 -0400 Subject: [PATCH 50/54] Final addition of definitions --- src/components/Definition/data.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 3e3fa30efc..973127a8aa 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -11,23 +11,23 @@ export type Term = { export const terms: Term[] = [ { - titles: ["IP CIDR", "CIDR"], + titles: ["MCP server", "MCP"], meaning: - "Classless Inter-Domain Routing is a method used to allocate IP addresses more efficiently and route IP packets more flexibly than the older class-based system.", - link: "https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing", + "MCP (Model Context Protocol) is an open standard that allows AI models to access external data, tools, and services, and potentially use them to automate workflows.", + link: "https://en.wikipedia.org/wiki/Model_Context_Protocol", pluralEnding: "s", }, { titles: ["IP CIDR", "CIDR"], meaning: - "Classless Inter-Domain Routing is a method used to allocate IP addresses more efficiently and route IP packets more flexibly than the older class-based system.", + "Classless Inter-Domain Routing is a method used to allocate IP addresses more efficiently and route IP packets more flexibly than older class-based systems.", link: "https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing", pluralEnding: "s", }, { titles: ["shadow IT"], meaning: - "Shadow IT refers IT systems, software, and cloud services used by individuals within an organization without the IT department's knowledge or approval", + "Shadow IT refers to IT systems, software, and cloud services used by individuals within an organization without the IT department's knowledge or approval", link: "https://en.wikipedia.org/wiki/Shadow_IT", }, { @@ -86,13 +86,13 @@ export const terms: Term[] = [ { titles: ["Traffic Policy", "Traffic Policies"], meaning: - "Traffic Policy is a configuration language that offers you the flexibility to filter, match, manage and orchestrate traffic to your endpoints. For example, you can add authentication, send custom response, rate limit traffic, and more.", + "Traffic Policy is a configuration language that enables you to filter, match, manage and orchestrate traffic to your endpoints. For example, you can add authentication, send custom response, rate limit traffic, and more.", link: "/docs/traffic-policy/", }, { titles: ["Endpoint pool", "Endpoint Pooling"], meaning: - 'When your create two endpoints with the same URL (and binding), those endpoints automatically form a "pool" and share incoming traffic.', + 'When your create two ngrok endpoints with the same URL (and binding), those endpoints automatically form a "pool" and share incoming traffic.', link: "/docs/universal-gateway/endpoint-pooling/", pluralEnding: "s", }, @@ -100,7 +100,7 @@ export const terms: Term[] = [ titles: ["OWASP"], caseSensitive: true, meaning: - "OWASP: The Open Web Application Security Project. This non-profit organization is dedicated to improving software security through providing resources, tools, and community support.", + "The Open Web Application Security Project is a non-profit organization dedicated to improving software security through providing resources, tools, and community support.", link: "https://owasp.org/about/", }, { @@ -112,7 +112,7 @@ export const terms: Term[] = [ { titles: ["TLS Termination"], meaning: - "TLS termination is the process of decrypting incoming TLS (Transport Layer Security) traffic at a server or load balancer before passing the unencrypted traffic to internal systems.", + "TLS (Transport Layer Security) termination is the process of decrypting incoming TLS traffic at a server or load balancer before passing the unencrypted traffic to internal systems.", link: "/docs/universal-gateway/tls-termination/", }, { @@ -126,20 +126,20 @@ export const terms: Term[] = [ titles: ["reverse proxy", "reverse proxies"], link: "https://en.wikipedia.org/wiki/Reverse_proxy", meaning: - "Reverse proxies are computer infrastructure, such as servers or cloud services, that intercept and then forward traffic to the upstream services. They are an extra security layer between public traffic and your internal services.", + "Reverse proxies are an extra security layer between public traffic and your internal services. They live on servers or cloud services, and they intercept and forward traffic to upstream services.", }, { titles: ["WAF"], link: "https://en.wikipedia.org/wiki/Web_application_firewall", caseSensitive: true, meaning: - "A web application firewall (WAF) is a type of reverse proxy that protects web services by filtering and monitoring HTTP traffic.", + "A web application firewall (WAF) is an intermediary service in the cloud or on a server that protects web services by filtering and monitoring HTTP traffic.", }, { titles: ["Gateway API CRD", "Gateway API"], link: "https://gateway-api.sigs.k8s.io/guides/", meaning: - "Gateway API CRDs (Custom Resource Definitions) are a set of standardized, extensible resources that define and manage networking configurations like routing, gateways, and traffic policies in a more expressive and role-oriented way than Ingress.", + "Gateway API CRDs (Custom Resource Definitions) are a set of standardized, extensible resources that manage networking configurations like routing, gateways, and traffic policies.", pluralEnding: "s", }, { From 2f7c0f61a30a5824d50178661c1c6db3371a44ac Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 26 Jun 2025 10:41:47 -0400 Subject: [PATCH 51/54] Deserialized whole term. Hide redundant --- src/components/Definition/index.tsx | 74 +++++++++++++++++++---------- src/plugins/definition-wrapper.js | 3 +- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/components/Definition/index.tsx b/src/components/Definition/index.tsx index 0890b25b56..8705791fc4 100644 --- a/src/components/Definition/index.tsx +++ b/src/components/Definition/index.tsx @@ -21,18 +21,34 @@ type DefinitionProps = { meaning?: string; link?: string; className?: string; - // If true, the definition will not be rendered if the last - // path segment matches the link. This is useful to avoid - // rendering definitions that link to the current page. - hideIfInPath?: boolean; + // The stringified term provided by the definitionwrapper + wrapperTermString?: string; + // If true, the definition will not be rendered on pages + // where the content most likely already explains the term + hideIfRedundant?: boolean; }; +function verifyLink(link: string | undefined, linkType: string | null): void { + if (link && !linkType) + throw new Error(` link must be a valid URL. Received ${link}`); + + if (link?.includes("localhost:")) + throw new Error( + ` link must not be a localhost URL. Received ${link}`, + ); +} + +function findMatchingTerm(content: string) { + return terms.find((term) => term.titles.includes(content)); +} + export function Definition({ children, meaning, link, className, - hideIfInPath, + hideIfRedundant, + wrapperTermString, }: DefinitionProps): React.ReactElement { if (!children) throw new Error(" requires children"); const linkType = link?.startsWith("http") @@ -40,35 +56,41 @@ export function Definition({ : link?.startsWith("/") ? "internal" : null; - if (link && !linkType) - throw new Error(` link must be a valid URL. Received ${link}`); - if (link?.includes("localhost:")) - throw new Error( - ` link must not be a localhost URL. Received ${link}`, - ); + verifyLink(link, linkType); - const { pathname } = useLocation(); + const parsedWrapperTerm = wrapperTermString + ? JSON.parse(wrapperTermString) + : null; - // Don't get the match if the meaning or link is provided + // Don't get the match if the meaning is provided const match = - meaning && link - ? null - : terms.find((term) => term.titles.includes(children.toString())); - const data = { - meaning: meaning || match?.meaning, - // If link is to the current page, don't use it. No need to - // link to the same page. - link: link || match?.link, - }; + parsedWrapperTerm || meaning ? null : findMatchingTerm(children.toString()); - if (data.link && hideIfInPath) { + const data = match || + parsedWrapperTerm || { + meaning, + link, + }; + + const { pathname } = useLocation(); + + if (data.link && hideIfRedundant) { const pathSegments = pathname.split("/"); const lastPathSegment = pathSegments[pathSegments.length - 2]; + // If the link is in the current path, don't render + // the definition component. Probably redundant. if (lastPathSegment && data.link.includes(lastPathSegment)) { - // If the link is in the current path, don't render - // the definition component. Prevents showing - // definitions that link to the current page. + return <>{children}; + } + + // If the last path segment matches any of the titles, + // don't render the definition component. Probably redundant. + if ( + data.titles.some((title: string) => + lastPathSegment?.includes(title.split(" ").join("-").toLowerCase()), + ) + ) { return <>{children}; } } diff --git a/src/plugins/definition-wrapper.js b/src/plugins/definition-wrapper.js index b816c38352..4695b57c18 100644 --- a/src/plugins/definition-wrapper.js +++ b/src/plugins/definition-wrapper.js @@ -121,9 +121,10 @@ module.exports = function remarkWordWrapper(stuff) { tagName: "Definition", properties: { meaning: matchingTerm.meaning, - hideIfInPath: true, + hideIfRedundant: true, link: matchingTerm.link, className: styles, + wrapperTermString: JSON.stringify(matchingTerm), }, children: [ { From 56f19c9258c4e131e0df2b7e1e83c9efe292609f Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 26 Jun 2025 11:22:25 -0400 Subject: [PATCH 52/54] Fix configexample --- src/components/ConfigExample.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ConfigExample.tsx b/src/components/ConfigExample.tsx index aa3908fc80..bce28d3f98 100644 --- a/src/components/ConfigExample.tsx +++ b/src/components/ConfigExample.tsx @@ -19,7 +19,7 @@ const showExample = ( ) => { const titleToUse = title || defaultTitle; return ( - + Date: Thu, 26 Jun 2025 12:04:48 -0400 Subject: [PATCH 53/54] Okay actually readu to merge --- src/components/Definition/data.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 973127a8aa..230805dba5 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -1,3 +1,6 @@ +/** + * Tip: When adding titles, make sure the longest variation is first in the array. + */ export type Term = { titles: string[]; meaning: string; @@ -90,7 +93,7 @@ export const terms: Term[] = [ link: "/docs/traffic-policy/", }, { - titles: ["Endpoint pool", "Endpoint Pooling"], + titles: ["Endpoint Pooling", "Endpoint pool"], meaning: 'When your create two ngrok endpoints with the same URL (and binding), those endpoints automatically form a "pool" and share incoming traffic.', link: "/docs/universal-gateway/endpoint-pooling/", From dd342c4b78ae9216b5d0b2798267c9bbdd51d6b9 Mon Sep 17 00:00:00 2001 From: Shaquil Hansford Date: Thu, 26 Jun 2025 12:39:33 -0400 Subject: [PATCH 54/54] Just remove the full name for OpenID for now, it's a nuisance --- src/components/Definition/data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Definition/data.ts b/src/components/Definition/data.ts index 230805dba5..e150d59740 100644 --- a/src/components/Definition/data.ts +++ b/src/components/Definition/data.ts @@ -34,7 +34,7 @@ export const terms: Term[] = [ link: "https://en.wikipedia.org/wiki/Shadow_IT", }, { - titles: ["OpenID Connect", "OIDC"], + titles: ["OIDC"], meaning: "OpenID Connect (OIDC) is an authentication protocol that enables third-party applications to confirm a user's identity and access basic profile details through a single sign-on (SSO) process.", link: "https://en.wikipedia.org/wiki/OpenID",