From 6d7005723d31b47ad38e9835f0b458f91282eed6 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Sun, 7 Sep 2025 22:47:59 +0200 Subject: [PATCH 01/40] small improvements --- .env.example | 1 + app/components/icon-link.tsx | 28 +++++++ app/components/page-mdx-article.tsx | 4 +- ...d-breadcrumbs.tsx => build-breadcrumbs.ts} | 6 +- app/components/sidebar/mobile-sidebar.tsx | 12 ++- app/components/sidebar/sidebar-section.tsx | 15 ++-- app/components/sidebar/sidebar.tsx | 8 +- ...mbs.test.tsx => build-breadcrumbs.test.ts} | 26 +++---- app/components/versions-dropdown.tsx | 12 +-- app/env.server.ts | 4 +- app/hooks/use-previous-next-pages.ts | 11 ++- app/root.tsx | 9 ++- app/routes/documentation-homepage.tsx | 20 ++++- app/routes/documentation-layout.tsx | 12 ++- app/routes/documentation-page.tsx | 21 +++++- app/ui/accordion.tsx | 6 +- app/ui/alert.tsx | 5 +- app/ui/breadcrumbs.tsx | 16 ++-- app/ui/icon-button.tsx | 2 +- app/utils/get-domain.ts | 5 ++ app/utils/seo.ts | 32 ++++++++ app/utils/split-slug-and-append-version.ts | 19 ----- app/utils/split-slug.ts | 22 +++--- .../split-slug-and-append-version.test.ts | 70 ----------------- app/utils/tests/split-slug.test.ts | 71 ------------------ app/utils/version-resolvers.ts | 9 +-- .../statics/images/package-image-1200x630.jpg | Bin 0 -> 41841 bytes public/statics/images/package-logo.png | Bin 0 -> 12573 bytes 28 files changed, 202 insertions(+), 244 deletions(-) create mode 100644 app/components/icon-link.tsx rename app/components/sidebar/{build-breadcrumbs.tsx => build-breadcrumbs.ts} (74%) rename app/components/sidebar/tests/{build-breadcrumbs.test.tsx => build-breadcrumbs.test.ts} (72%) create mode 100644 app/utils/get-domain.ts create mode 100644 app/utils/seo.ts delete mode 100644 app/utils/split-slug-and-append-version.ts delete mode 100644 app/utils/tests/split-slug-and-append-version.test.ts delete mode 100644 app/utils/tests/split-slug.test.ts create mode 100644 public/statics/images/package-image-1200x630.jpg create mode 100644 public/statics/images/package-logo.png diff --git a/.env.example b/.env.example index d6b7df4..f2c1ef0 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ GITHUB_OWNER="github-owner" # Your username or organization name (Optional. For edit/report an issue for the documentation page) GITHUB_REPO="github-repo" # Repository name (Optional. For edit/report an issue for the documentation page) APP_ROOT_PATH="/path/to/your/app" # Optional. Default is `process.cwd()` +GITHUB_REPO_URL="github-repo-url" #Optional diff --git a/app/components/icon-link.tsx b/app/components/icon-link.tsx new file mode 100644 index 0000000..8e040fc --- /dev/null +++ b/app/components/icon-link.tsx @@ -0,0 +1,28 @@ +import type { ComponentProps } from "react" +import { Icon } from "~/ui/icon/icon" +import type { IconName } from "~/ui/icon/icons/types" +import { cn } from "~/utils/css" + +interface IconLinkProps extends ComponentProps<"a"> { + name: IconName +} + +export const IconLink = ({ name, className, ...props }: IconLinkProps) => { + const { href } = props + const isExternal = typeof href === "string" && /^https?:\/\//i.test(href) + return ( + + + + ) +} diff --git a/app/components/page-mdx-article.tsx b/app/components/page-mdx-article.tsx index 89f8de2..cea48d2 100644 --- a/app/components/page-mdx-article.tsx +++ b/app/components/page-mdx-article.tsx @@ -10,9 +10,9 @@ export default function PageMdxArticle({ page }: { page: Page }) { {page.title} {page.description && ( - + <p className="my-6 font-normal text-[var(--color-text-muted)] text-base sm:text-lg md:text-xl"> {page.description} - +

)} diff --git a/app/components/sidebar/build-breadcrumbs.tsx b/app/components/sidebar/build-breadcrumbs.ts similarity index 74% rename from app/components/sidebar/build-breadcrumbs.tsx rename to app/components/sidebar/build-breadcrumbs.ts index 5efc4c0..f921c37 100644 --- a/app/components/sidebar/build-breadcrumbs.tsx +++ b/app/components/sidebar/build-breadcrumbs.ts @@ -1,5 +1,4 @@ -import { href } from "react-router" -import { splitSlugAndAppendVersion } from "~/utils/split-slug-and-append-version" +import { splitSlug } from "~/utils/split-slug" import type { SidebarSection } from "./sidebar" // builds a breadcrumb trail from sidebar sections based on the current pathname @@ -8,7 +7,8 @@ export const buildBreadcrumb = (items: SidebarSection[], pathname: string) => { const walk = (section: SidebarSection, acc: string[]) => { for (const doc of section.documentationPages) { - const docPath = href("/:version/:section/:subsection?/:filename", splitSlugAndAppendVersion(doc.slug)) + const { section: sec, subsection, filename } = splitSlug(doc.slug) + const docPath = `/${[sec, subsection, filename].filter(Boolean).join("/")}` if (docPath === pathname) { trail = [...acc, section.title, doc.title] return true diff --git a/app/components/sidebar/mobile-sidebar.tsx b/app/components/sidebar/mobile-sidebar.tsx index f0c06f7..7f506ed 100644 --- a/app/components/sidebar/mobile-sidebar.tsx +++ b/app/components/sidebar/mobile-sidebar.tsx @@ -1,6 +1,9 @@ +import { useParams } from "react-router" +import { useDocumentationLayoutLoaderData } from "~/hooks/use-documentation-layout-loader-data" import { BreadcrumbItem, Breadcrumbs } from "~/ui/breadcrumbs" import { Icon } from "~/ui/icon/icon" import { cn } from "~/utils/css" +import { buildBreadcrumb } from "./build-breadcrumbs" import { useMobileSidebar } from "./mobile-sidebar-context" import type { SidebarSection } from "./sidebar" import { SidebarContent } from "./sidebar-content" @@ -20,7 +23,13 @@ const MobileSidebarMenuButton = () => { ) } -export const MobileSidebarHeader = ({ breadcrumbs }: { breadcrumbs: string[] }) => { +export const MobileSidebarHeader = () => { + const params = useParams() + const { sidebarTree: items } = useDocumentationLayoutLoaderData() + const { section, subsection, filename } = params + const currentPath = `/${[section, subsection, filename].filter(Boolean).join("/")}` + + const breadcrumbs = buildBreadcrumb(items, currentPath) return (
@@ -78,7 +87,6 @@ export const MobileSidebarPanel = ({ isOpen ? "translate-x-0" : "-translate-x-full", className )} - aria-modal="true" aria-label="Navigation menu" > diff --git a/app/components/sidebar/sidebar-section.tsx b/app/components/sidebar/sidebar-section.tsx index c5fb493..0808300 100644 --- a/app/components/sidebar/sidebar-section.tsx +++ b/app/components/sidebar/sidebar-section.tsx @@ -1,6 +1,8 @@ -import { NavLink, href } from "react-router" +import { NavLink, href, useRouteLoaderData } from "react-router" +import type { loader } from "~/root" import { AccordionItem } from "~/ui/accordion" -import { splitSlugAndAppendVersion } from "~/utils/split-slug-and-append-version" +import { splitSlug } from "~/utils/split-slug" +import { versions } from "~/utils/versions" import type { SidebarSection } from "./sidebar" const getIndentClass = (depth: number) => { @@ -29,11 +31,14 @@ const SectionTitle = ({ title }: { title: string }) => { } const SectionItemLink = ({ documentPage, depth, onItemClick }: SectionItemLinkProps) => { + const data = useRouteLoaderData("root") + const version = data?.version ?? versions[0] const indentClass = getIndentClass(depth) + const { section, subsection, filename } = splitSlug(documentPage.slug) return ( `block rounded-md px-3 py-2 text-xs sm:text-sm md:text-base ${indentClass} @@ -78,8 +83,8 @@ export const SectionItem = ({ item, depth = 0, onItemClick }: SectionItemProps) return ( diff --git a/app/components/sidebar/sidebar.tsx b/app/components/sidebar/sidebar.tsx index 42a7a43..431f345 100644 --- a/app/components/sidebar/sidebar.tsx +++ b/app/components/sidebar/sidebar.tsx @@ -1,6 +1,4 @@ -import { useLocation } from "react-router" import { cn } from "~/utils/css" -import { buildBreadcrumb } from "./build-breadcrumbs" import { DesktopSidebarPanel } from "./desktop-sidebar" import { MobileSidebarHeader, MobileSidebarOverlay, MobileSidebarPanel } from "./mobile-sidebar" import { MobileSidebarProvider } from "./mobile-sidebar-context" @@ -20,16 +18,12 @@ interface SidebarProps { } export const Sidebar = ({ items, className = "" }: SidebarProps) => { - const location = useLocation() - const breadcrumbs = buildBreadcrumb(items, location.pathname) - return ( <> -
- +
diff --git a/app/components/sidebar/tests/build-breadcrumbs.test.tsx b/app/components/sidebar/tests/build-breadcrumbs.test.ts similarity index 72% rename from app/components/sidebar/tests/build-breadcrumbs.test.tsx rename to app/components/sidebar/tests/build-breadcrumbs.test.ts index 723b4e6..74ae7ae 100644 --- a/app/components/sidebar/tests/build-breadcrumbs.test.tsx +++ b/app/components/sidebar/tests/build-breadcrumbs.test.ts @@ -1,18 +1,17 @@ import { describe, expect, it, vi } from "vitest" import type { SidebarSection } from "../sidebar" -vi.mock("~/utils/split-slug-and-append-version", () => ({ - splitSlugAndAppendVersion: (slug: string) => { +vi.mock("~/utils/split-slug", () => ({ + splitSlug: (slug: string) => { const parts = slug.split("/").filter(Boolean) - const version = "v1.0.0" if (parts.length === 2) { const [section, filename] = parts - return { version, section, filename } + return { section, filename } } if (parts.length === 3) { const [section, subsection, filename] = parts - return { version, section, subsection, filename } + return { section, subsection, filename } } throw new Error(`Bad slug in test: ${slug}`) @@ -33,7 +32,7 @@ const makeSection = (overrides: Partial = {}) => ({ ...overrides, }) -describe("buildBreadcrumb (versioned paths via splitSlugAndAppendVersion)", () => { +describe("buildBreadcrumb", () => { it("returns [] when pathname doesn't match any doc", () => { const items = [ makeSection({ @@ -42,7 +41,7 @@ describe("buildBreadcrumb (versioned paths via splitSlugAndAppendVersion)", () = documentationPages: [makeDoc("getting-started/intro", "Intro")], }), ] - expect(buildBreadcrumb(items, "/v1.0.0/getting-started/unknown")).toEqual([]) + expect(buildBreadcrumb(items, "/getting-started/unknown")).toEqual([]) }) it("returns [section, doc] for a top-level doc", () => { @@ -53,7 +52,7 @@ describe("buildBreadcrumb (versioned paths via splitSlugAndAppendVersion)", () = documentationPages: [makeDoc("getting-started/intro", "Intro")], }), ] - expect(buildBreadcrumb(items, "/v1.0.0/getting-started/intro")).toEqual(["Getting Started", "Intro"]) + expect(buildBreadcrumb(items, "/getting-started/intro")).toEqual(["Getting Started", "Intro"]) }) it("returns full trail for a nested doc (root → sub → doc)", () => { @@ -71,10 +70,11 @@ describe("buildBreadcrumb (versioned paths via splitSlugAndAppendVersion)", () = documentationPages: [makeDoc("configuration/setup", "Setup")], }), ] - expect(buildBreadcrumb(items, "/v1.0.0/configuration/advanced/tuning")).toEqual([ - "Configuration", - "Advanced", - "Tuning", - ]) + expect(buildBreadcrumb(items, "/configuration/advanced/tuning")).toEqual(["Configuration", "Advanced", "Tuning"]) + }) + + it("returns [] for an empty sidebar", () => { + const items: MinimalSection[] = [] + expect(buildBreadcrumb(items, "/any-path")).toEqual([]) }) }) diff --git a/app/components/versions-dropdown.tsx b/app/components/versions-dropdown.tsx index bf64dae..53f8bd6 100644 --- a/app/components/versions-dropdown.tsx +++ b/app/components/versions-dropdown.tsx @@ -1,12 +1,14 @@ import { useState } from "react" -import { useNavigate } from "react-router" +import { useNavigate, useRouteLoaderData } from "react-router" +import type { loader } from "~/root" import { Icon } from "~/ui/icon/icon" -import { getCurrentVersion, homepageUrlWithVersion, isKnownVersion } from "~/utils/version-resolvers" +import { homepageUrlWithVersion, isKnownVersion } from "~/utils/version-resolvers" import { versions } from "~/utils/versions" export function VersionDropdown() { const navigate = useNavigate() - const { version: currentVersion } = getCurrentVersion() + const data = useRouteLoaderData("root") + const currentVersion = data?.version ?? versions[0] const [selectedVersion, setSelectedVersion] = useState(currentVersion) function onChange(e: React.ChangeEvent) { @@ -29,7 +31,7 @@ export function VersionDropdown() { REACT ROUTER DEVTOOLS
- -
+
+ {GITHUB_REPO_URL && }
-
- - -
diff --git a/app/ui/icon-button.tsx b/app/ui/icon-button.tsx index 0a47a61..b7c7bbf 100644 --- a/app/ui/icon-button.tsx +++ b/app/ui/icon-button.tsx @@ -13,7 +13,7 @@ export const IconButton = ({ name, className, ...props }: IconButtonProps) => { +
{content}
) From c1a4fbe431de26652e4a5fe8a947517b36f680a4 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 16:17:19 +0200 Subject: [PATCH 13/40] added on PR fly deploy action --- .github/workflows/{validate.yml => ci.yml} | 21 +++++++++++++++++++++ .github/workflows/fly-deploy.yml | 18 ------------------ 2 files changed, 21 insertions(+), 18 deletions(-) rename .github/workflows/{validate.yml => ci.yml} (73%) delete mode 100644 .github/workflows/fly-deploy.yml diff --git a/.github/workflows/validate.yml b/.github/workflows/ci.yml similarity index 73% rename from .github/workflows/validate.yml rename to .github/workflows/ci.yml index c1598c4..06aa90f 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/ci.yml @@ -67,3 +67,24 @@ jobs: # Only works if you set `reportOnFailure: true` in your vite config as specified above if: always() uses: davelosert/vitest-coverage-report-action@v2 + + + deploy: + needs: [lint, typecheck, check-unused, vitest] + name: 🚀 Deploy PR Preview + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: forge-42/fly-deploy@v1.0.0-rc.2 + id: deploy + env: + FLY_ORG: ${{ vars.FLY_ORG }} + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + FLY_REGION: ${{ vars.FLY_REGION }} + with: + app_name: ${{ env.FLY_ORG }}-${{ github.event.number }} + env_vars: | + APP_ENV=staging + GITHUB_OWNER: "forge-42" + GITHUB_REPO: "docs-template" + GITHUB_REPO_URL: "https://github.com/forge-42/docs-template" diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml deleted file mode 100644 index b0c246e..0000000 --- a/.github/workflows/fly-deploy.yml +++ /dev/null @@ -1,18 +0,0 @@ -# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ - -name: Fly Deploy -on: - push: - branches: - - main -jobs: - deploy: - name: Deploy app - runs-on: ubuntu-latest - concurrency: deploy-group # optional: ensure only one action runs at a time - steps: - - uses: actions/checkout@v4 - - uses: superfly/flyctl-actions/setup-flyctl@master - - run: flyctl deploy --remote-only - env: - FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} From 219f3aa07c2131b0ff70f676221dd3d6b8454db7 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 16:18:26 +0200 Subject: [PATCH 14/40] removed flydotio/dockerfile --- package.json | 1 - pnpm-lock.yaml | 357 ------------------------------------------------- 2 files changed, 358 deletions(-) diff --git a/package.json b/package.json index ca6dc59..e4e902b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "@babel/preset-typescript": "7.26.0", "@biomejs/biome": "1.9.4", "@dotenvx/dotenvx": "1.34.0", - "@flydotio/dockerfile": "0.7.10", "@react-router/dev": "7.2.0", "@tailwindcss/typography": "0.5.16", "@tailwindcss/vite": "4.0.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9adf206..251c9b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,9 +93,6 @@ importers: '@dotenvx/dotenvx': specifier: 1.34.0 version: 1.34.0 - '@flydotio/dockerfile': - specifier: 0.7.10 - version: 0.7.10(@types/node@22.13.1) '@react-router/dev': specifier: 7.2.0 version: 7.2.0(@types/node@22.13.1)(babel-plugin-macros@3.1.0)(jiti@2.5.1)(lightningcss@1.30.1)(react-router@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(tsx@4.19.2)(typescript@5.7.3)(vite@6.2.0(@types/node@22.13.1)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.19.2)(yaml@2.8.1))(yaml@2.8.1) @@ -813,11 +810,6 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@flydotio/dockerfile@0.7.10': - resolution: {integrity: sha512-dTXqBjCl7nFmnhlyeDjjPtX+sdfYBWFH9PUKNqAYttvBiczKcYXxr7/0A0wZ+g1FB1tmMzsOzedgr6xap/AB9g==} - engines: {node: '>=16.0.0'} - hasBin: true - '@forge42/seo-tools@1.3.0': resolution: {integrity: sha512-yxpkeyYyZhFzTpuq9rtcx6FRVZD0NTcVDS2ptrVG7nobnHQnANlLJXkY343GOocHGTygdK35Hyu/iU1nxsEGuA==} @@ -847,15 +839,6 @@ packages: wrangler: optional: true - '@inquirer/checkbox@4.2.2': - resolution: {integrity: sha512-E+KExNurKcUJJdxmjglTl141EwxWyAHplvsYJQgSwXf8qiNWkTxTuCCqmhFEmbIXd4zLaGMfQFJ6WrZ7fSeV3g==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/confirm@5.1.15': resolution: {integrity: sha512-SwHMGa8Z47LawQN0rog0sT+6JpiL0B7eW9p1Bb7iCeKDGTI5Ez25TSc2l8kw52VV7hA4sX/C78CGkMrKXfuspA==} engines: {node: '>=18'} @@ -865,15 +848,6 @@ packages: '@types/node': optional: true - '@inquirer/confirm@5.1.16': - resolution: {integrity: sha512-j1a5VstaK5KQy8Mu8cHmuQvN1Zc62TbLhjJxwHvKPPKEoowSF6h/0UdOpA9DNdWZ+9Inq73+puRq1df6OJ8Sag==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/core@10.1.15': resolution: {integrity: sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==} engines: {node: '>=18'} @@ -883,109 +857,10 @@ packages: '@types/node': optional: true - '@inquirer/core@10.2.0': - resolution: {integrity: sha512-NyDSjPqhSvpZEMZrLCYUquWNl+XC/moEcVFqS55IEYIYsY0a1cUCevSqk7ctOlnm/RaSBU5psFryNlxcmGrjaA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/editor@4.2.18': - resolution: {integrity: sha512-yeQN3AXjCm7+Hmq5L6Dm2wEDeBRdAZuyZ4I7tWSSanbxDzqM0KqzoDbKM7p4ebllAYdoQuPJS6N71/3L281i6w==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/expand@4.0.18': - resolution: {integrity: sha512-xUjteYtavH7HwDMzq4Cn2X4Qsh5NozoDHCJTdoXg9HfZ4w3R6mxV1B9tL7DGJX2eq/zqtsFjhm0/RJIMGlh3ag==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/external-editor@1.0.1': - resolution: {integrity: sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/figures@1.0.13': resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} engines: {node: '>=18'} - '@inquirer/input@4.2.2': - resolution: {integrity: sha512-hqOvBZj/MhQCpHUuD3MVq18SSoDNHy7wEnQ8mtvs71K8OPZVXJinOzcvQna33dNYLYE4LkA9BlhAhK6MJcsVbw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/number@3.0.18': - resolution: {integrity: sha512-7exgBm52WXZRczsydCVftozFTrrwbG5ySE0GqUd2zLNSBXyIucs2Wnm7ZKLe/aUu6NUg9dg7Q80QIHCdZJiY4A==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/password@4.0.18': - resolution: {integrity: sha512-zXvzAGxPQTNk/SbT3carAD4Iqi6A2JS2qtcqQjsL22uvD+JfQzUrDEtPjLL7PLn8zlSNyPdY02IiQjzoL9TStA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/prompts@7.8.4': - resolution: {integrity: sha512-MuxVZ1en1g5oGamXV3DWP89GEkdD54alcfhHd7InUW5BifAdKQEK9SLFa/5hlWbvuhMPlobF0WAx7Okq988Jxg==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/rawlist@4.1.6': - resolution: {integrity: sha512-KOZqa3QNr3f0pMnufzL7K+nweFFCCBs6LCXZzXDrVGTyssjLeudn5ySktZYv1XiSqobyHRYYK0c6QsOxJEhXKA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/search@3.1.1': - resolution: {integrity: sha512-TkMUY+A2p2EYVY3GCTItYGvqT6LiLzHBnqsU1rJbrpXUijFfM6zvUx0R4civofVwFCmJZcKqOVwwWAjplKkhxA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/select@4.3.2': - resolution: {integrity: sha512-nwous24r31M+WyDEHV+qckXkepvihxhnyIaod2MG7eCE6G0Zm/HUF6jgN8GXgf4U7AU6SLseKdanY195cwvU6w==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@3.0.8': resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} engines: {node: '>=18'} @@ -1884,9 +1759,6 @@ packages: async@3.2.3: resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - babel-dead-code-elimination@1.0.10: resolution: {integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==} @@ -1974,9 +1846,6 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - chardet@2.1.0: - resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} - check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -2194,10 +2063,6 @@ packages: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} - diff@7.0.0: - resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} - engines: {node: '>=0.3.1'} - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -2239,11 +2104,6 @@ packages: engines: {node: '>=14'} hasBin: true - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true - electron-to-chromium@1.5.208: resolution: {integrity: sha512-ozZyibehoe7tOhNaf16lKmljVf+3npZcJIEbJRVftVsmAg5TeA1mGS9dVCZzOwr2xT7xK15V0p7+GZqSPgkuPg==} @@ -2375,9 +2235,6 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -2553,10 +2410,6 @@ packages: typescript: optional: true - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -2578,15 +2431,6 @@ packages: inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - inquirer@12.9.4: - resolution: {integrity: sha512-5bV3LOgLtMAiJq1QpaUddfRrvaX59wiMYppS7z2jNRSQ64acI0yqx7WMxWhgymenSXOyD657g9tlsTjqGYM8sg==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -2684,11 +2528,6 @@ packages: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} - jake@10.9.4: - resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} - engines: {node: '>=10'} - hasBin: true - jiti@2.5.1: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true @@ -3065,10 +2904,6 @@ packages: resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - minimatch@9.0.1: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} @@ -3595,25 +3430,15 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - run-async@4.0.6: - resolution: {integrity: sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==} - engines: {node: '>=0.12.0'} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - scheduler@0.25.0: resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} @@ -3644,10 +3469,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.3: - resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} - engines: {node: '>= 0.4'} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -4799,17 +4620,6 @@ snapshots: '@floating-ui/utils@0.2.10': {} - '@flydotio/dockerfile@0.7.10(@types/node@22.13.1)': - dependencies: - chalk: 5.4.1 - diff: 7.0.0 - ejs: 3.1.10 - inquirer: 12.9.4(@types/node@22.13.1) - shell-quote: 1.8.3 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - '@forge42/seo-tools@1.3.0(typescript@5.7.3)': dependencies: url-pattern: 1.0.3 @@ -4842,16 +4652,6 @@ snapshots: hono: 4.6.20 minimatch: 9.0.5 - '@inquirer/checkbox@4.2.2(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.13.1) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.13.1 - '@inquirer/confirm@5.1.15(@types/node@22.13.1)': dependencies: '@inquirer/core': 10.1.15(@types/node@22.13.1) @@ -4859,13 +4659,6 @@ snapshots: optionalDependencies: '@types/node': 22.13.1 - '@inquirer/confirm@5.1.16(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - optionalDependencies: - '@types/node': 22.13.1 - '@inquirer/core@10.1.15(@types/node@22.13.1)': dependencies: '@inquirer/figures': 1.0.13 @@ -4879,108 +4672,8 @@ snapshots: optionalDependencies: '@types/node': 22.13.1 - '@inquirer/core@10.2.0(@types/node@22.13.1)': - dependencies: - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.13.1) - ansi-escapes: 4.3.2 - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/editor@4.2.18(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/external-editor': 1.0.1(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/expand@4.0.18(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/external-editor@1.0.1(@types/node@22.13.1)': - dependencies: - chardet: 2.1.0 - iconv-lite: 0.6.3 - optionalDependencies: - '@types/node': 22.13.1 - '@inquirer/figures@1.0.13': {} - '@inquirer/input@4.2.2(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/number@3.0.18(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/password@4.0.18(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - ansi-escapes: 4.3.2 - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/prompts@7.8.4(@types/node@22.13.1)': - dependencies: - '@inquirer/checkbox': 4.2.2(@types/node@22.13.1) - '@inquirer/confirm': 5.1.16(@types/node@22.13.1) - '@inquirer/editor': 4.2.18(@types/node@22.13.1) - '@inquirer/expand': 4.0.18(@types/node@22.13.1) - '@inquirer/input': 4.2.2(@types/node@22.13.1) - '@inquirer/number': 3.0.18(@types/node@22.13.1) - '@inquirer/password': 4.0.18(@types/node@22.13.1) - '@inquirer/rawlist': 4.1.6(@types/node@22.13.1) - '@inquirer/search': 3.1.1(@types/node@22.13.1) - '@inquirer/select': 4.3.2(@types/node@22.13.1) - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/rawlist@4.1.6(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/search@3.1.1(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.13.1) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.13.1 - - '@inquirer/select@4.3.2(@types/node@22.13.1)': - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.13.1) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.13.1 - '@inquirer/type@3.0.8(@types/node@22.13.1)': optionalDependencies: '@types/node': 22.13.1 @@ -5879,8 +5572,6 @@ snapshots: async@3.2.3: {} - async@3.2.6: {} - babel-dead-code-elimination@1.0.10: dependencies: '@babel/core': 7.28.3 @@ -5970,8 +5661,6 @@ snapshots: character-reference-invalid@2.0.1: {} - chardet@2.1.0: {} - check-error@2.1.1: {} chokidar@4.0.3: @@ -6152,8 +5841,6 @@ snapshots: diff@5.2.0: {} - diff@7.0.0: {} - dom-accessibility-api@0.5.16: {} dom-helpers@3.4.0: @@ -6209,10 +5896,6 @@ snapshots: minimatch: 9.0.1 semver: 7.7.2 - ejs@3.1.10: - dependencies: - jake: 10.9.4 - electron-to-chromium@1.5.208: {} emoji-regex@8.0.0: {} @@ -6399,10 +6082,6 @@ snapshots: fflate@0.8.2: {} - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -6605,10 +6284,6 @@ snapshots: optionalDependencies: typescript: 5.7.3 - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - ignore@5.3.2: {} import-fresh@3.3.1: @@ -6624,18 +6299,6 @@ snapshots: inline-style-parser@0.2.4: {} - inquirer@12.9.4(@types/node@22.13.1): - dependencies: - '@inquirer/core': 10.2.0(@types/node@22.13.1) - '@inquirer/prompts': 7.8.4(@types/node@22.13.1) - '@inquirer/type': 3.0.8(@types/node@22.13.1) - ansi-escapes: 4.3.2 - mute-stream: 2.0.0 - run-async: 4.0.6 - rxjs: 7.8.2 - optionalDependencies: - '@types/node': 22.13.1 - is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -6716,12 +6379,6 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 - jake@10.9.4: - dependencies: - async: 3.2.6 - filelist: 1.0.4 - picocolors: 1.1.1 - jiti@2.5.1: {} js-beautify@1.15.4: @@ -7272,10 +6929,6 @@ snapshots: dependencies: '@isaacs/brace-expansion': 5.0.0 - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.2 - minimatch@9.0.1: dependencies: brace-expansion: 2.0.2 @@ -7870,22 +7523,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.47.1 fsevents: 2.3.3 - run-async@4.0.6: {} - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - rxjs@7.8.2: - dependencies: - tslib: 2.8.1 - safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} - safer-buffer@2.1.2: {} - scheduler@0.25.0: {} section-matter@1.0.0: @@ -7909,8 +7554,6 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.3: {} - siginfo@2.0.0: {} signal-exit@3.0.7: {} From 69144df1c53210d22654d58c10b56e704fc94401 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 16:28:06 +0200 Subject: [PATCH 15/40] fixed content-ollections Page imports --- app/components/command-k/create-search-index.ts | 2 +- app/utils/llms-txt-builder.ts | 2 +- content-collections.ts | 10 ++++++++-- tsconfig.json | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/components/command-k/create-search-index.ts b/app/components/command-k/create-search-index.ts index 368e519..b102990 100644 --- a/app/components/command-k/create-search-index.ts +++ b/app/components/command-k/create-search-index.ts @@ -108,7 +108,7 @@ function extractHeadingSections(rawMdx: string) { export function createSearchIndex(pages: Page[]) { return pages - .filter((page) => page._meta.fileName !== "_index.mdx" && page.slug !== "_index") + .filter((page) => page._meta.fileName === "_index.mdx" && page.slug !== "_index") .flatMap((page) => { const pageSlug = getPageSlug(page) const pageUrl = pageSlug.startsWith("/") ? pageSlug : `/${pageSlug}` diff --git a/app/utils/llms-txt-builder.ts b/app/utils/llms-txt-builder.ts index 7fd413c..1e76b19 100644 --- a/app/utils/llms-txt-builder.ts +++ b/app/utils/llms-txt-builder.ts @@ -9,7 +9,7 @@ function buildSectionTitles(sections: Section[]) { function groupPagesByFolder(pages: Page[]) { return pages.reduce((groups, p) => { - const id = p.section ?? p._meta?.path?.split("/")[0] + const id = p.section ?? p._meta.path?.split("/")[0] if (!id) return groups const list = groups.get(id) ?? [] if (!groups.has(id)) groups.set(id, list) diff --git a/content-collections.ts b/content-collections.ts index 31d6c51..7a7c29a 100644 --- a/content-collections.ts +++ b/content-collections.ts @@ -11,7 +11,13 @@ const pageSchema = z.object({ summary: z.string(), description: z.string(), }) -const metaSchema = z.object({ path: z.string() }).partial().optional() +const metaSchema = z.object({ + filePath: z.string(), + fileName: z.string(), + directory: z.string(), + path: z.string(), + extension: z.string(), +}) const outputBaseSchema = z.object({ slug: z.string(), @@ -24,7 +30,7 @@ const pageOutputSchema = pageSchema.extend({ ...outputBaseSchema.shape, section: z.string().optional(), rawMdx: z.string(), - content: z.unknown(), + content: z.string(), }) export type Section = z.infer diff --git a/tsconfig.json b/tsconfig.json index 4b5d5e3..ebe0fea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,7 @@ "baseUrl": ".", "paths": { "~/*": ["./app/*"], - "content-collections": ["./.content-collections/generated"] + "content-collections": ["./content-collections.ts"] }, "rootDirs": [".", "./.react-router/types"], "plugins": [{ "name": "@react-router/dev" }], From 747aefecf542dd11cf2e8a376ccdb2a7ff508782 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 16:40:43 +0200 Subject: [PATCH 16/40] fly deploy workflow update --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06aa90f..2a55d53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: 🚀 Validation Pipeline +name: 🚀 Validation & Deploy Pipeline concurrency: group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -83,7 +83,7 @@ jobs: FLY_REGION: ${{ vars.FLY_REGION }} with: app_name: ${{ env.FLY_ORG }}-${{ github.event.number }} - env_vars: | + secrets: | APP_ENV=staging GITHUB_OWNER: "forge-42" GITHUB_REPO: "docs-template" From b231a6caab051b1ce30ce3bfca4dcc05c122bb09 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 16:42:08 +0200 Subject: [PATCH 17/40] fly deploy workflow update --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a55d53..8023d20 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,8 +83,8 @@ jobs: FLY_REGION: ${{ vars.FLY_REGION }} with: app_name: ${{ env.FLY_ORG }}-${{ github.event.number }} - secrets: | + env_vars: | APP_ENV=staging - GITHUB_OWNER: "forge-42" - GITHUB_REPO: "docs-template" - GITHUB_REPO_URL: "https://github.com/forge-42/docs-template" + GITHUB_OWNER=forge-42 + GITHUB_REPO=docs-template + GITHUB_REPO_URL=https://github.com/forge-42/docs-template From 2222945def7aebd2ba8e488b135dab5129760630 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 16:57:29 +0200 Subject: [PATCH 18/40] content-collections cli returned --- package.json | 4 +- pnpm-lock.yaml | 133 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e4e902b..f5766f0 100644 --- a/package.json +++ b/package.json @@ -28,9 +28,11 @@ "check:unused:fix": "knip --fix", "typegen": "react-router typegen", "generate:docs": "npx tsx scripts/generate-docs.ts --branch main", - "verify:docs": "tsx scripts/verify-docs.ts" + "verify:docs": "tsx scripts/verify-docs.ts", + "content-collections:build": "content-collections build" }, "dependencies": { + "@content-collections/cli": "0.1.7", "@content-collections/core": "0.10.0", "@content-collections/mdx": "0.2.2", "@content-collections/remix-vite": "0.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 251c9b8..ccbf141 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@content-collections/cli': + specifier: 0.1.7 + version: 0.1.7(@content-collections/core@0.10.0(typescript@5.7.3)) '@content-collections/core': specifier: 0.10.0 version: 0.10.0(typescript@5.7.3) @@ -405,15 +408,49 @@ packages: '@bundled-es-modules/tough-cookie@0.1.6': resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + '@clerc/core@0.44.0': + resolution: {integrity: sha512-o8RgXNcMRoHRujSw9OPDMxqrmoNk7HG0XAZkjZgOrSyIfRXCf85VLyHGBT3XmaOrPEGY964h02ZxMVFdp8RnNQ==} + + '@clerc/plugin-completions@0.44.0': + resolution: {integrity: sha512-r69KpaB+EcWccqe31OwK5iyJQZmgmhxJjEBL4RAGlRr2tu6MRX42AOmD3GDW+ZPHkc4D9NJdkqukLboTJlbycA==} + peerDependencies: + '@clerc/core': '*' + + '@clerc/plugin-help@0.44.0': + resolution: {integrity: sha512-QIH+Lrk6WZtXKNxEAA4gOk7dwseS7U0jTZ0TbJfcyOoNA3fF2p48UV8c7hmKk7OhfPS5009eJRW5CVQEgBB8Ng==} + peerDependencies: + '@clerc/core': '*' + + '@clerc/plugin-version@0.44.0': + resolution: {integrity: sha512-YETH54A0sO32oJcLABpb4P5FyhEkhIhe5oe3IXyeUj9/LMcInvKCm6x/gDMIUjTQuh0a5l4iton0A1RscAANhw==} + peerDependencies: + '@clerc/core': '*' + + '@clerc/utils@0.44.0': + resolution: {integrity: sha512-//1zl8UgVhv1NbqsRoCWWci0Y9uBxzAVn8TqoKZchDywGQNZWK6vQI/Ms9uGe3+PZTDXedoXbVjklOINcVC2aA==} + peerDependencies: + '@clerc/core': '*' + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} + '@content-collections/cli@0.1.7': + resolution: {integrity: sha512-dZn8vd6JSu2mXE1KYOEEq6Y7pwZ3vWjHE/LDj+9aSXNEddfXRGem2NNMO24NCuqFH/uIoVpS00Wnkj6gNqqnQw==} + hasBin: true + peerDependencies: + '@content-collections/core': 0.x + '@content-collections/core@0.10.0': resolution: {integrity: sha512-GDBYbvhoj9lHNlarY5wr+3PoO3m9GBMjftio9NXatLuZaenY+EHHNCcbbA3J+c06Q7WBYwNoLAaMX2I5N0duAg==} peerDependencies: typescript: ^5.0.2 + '@content-collections/integrations@0.3.0': + resolution: {integrity: sha512-He+TXQC94LO/1bNygTioh3J5H0K/mkFVPVkIrM5kHybprvi5bRmGa91ViZ6K6icFAzGH4jFD0iasR56fZcMGTA==} + peerDependencies: + '@content-collections/core': 0.x + '@content-collections/mdx@0.2.2': resolution: {integrity: sha512-7Xx8AohrSuq1jn/k44qWIq1s666KnksGPk64nnoY/T9mFZ7fZkdEtYezBsNpzkDMMKTnf65CNIvyFHtwTD2muA==} peerDependencies: @@ -1611,6 +1648,9 @@ packages: '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/text-table@0.2.5': + resolution: {integrity: sha512-hcZhlNvMkQG/k1vcZ6yHOl6WAYftQ2MLfTHcYRZ2xYZFD8tGVnE3qFV0lj1smQeDSR7/yY0PyuUalauf33bJeA==} + '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -2045,6 +2085,9 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -2107,6 +2150,9 @@ packages: electron-to-chromium@1.5.208: resolution: {integrity: sha512-ozZyibehoe7tOhNaf16lKmljVf+3npZcJIEbJRVftVsmAg5TeA1mGS9dVCZzOwr2xT7xK15V0p7+GZqSPgkuPg==} + emoji-regex@10.5.0: + resolution: {integrity: sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2484,6 +2530,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-platform@1.0.0: + resolution: {integrity: sha512-AKxe6+dvzAQsDXhhhxGRL9G67q5rKiyTL0BUl5mCyQz2NdvmqWNmMsjoCOIVdyXOYpP6MhkmZ1DPYGkfgv0MpA==} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -2705,6 +2754,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lite-emit@2.3.0: + resolution: {integrity: sha512-QMPrnwPho7lfkzZUN3a0RJ/oiwpt464eXf6aVh1HGOYh+s7Utu78q3FcFbW59c8TNWWQaz9flKN1cEb8dmxD+g==} + lodash.castarray@4.4.0: resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} @@ -3558,6 +3610,10 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@6.1.0: + resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} + engines: {node: '>=16'} + string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -3618,6 +3674,9 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} @@ -3703,6 +3762,9 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-flag@3.0.0: + resolution: {integrity: sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==} + typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -4036,6 +4098,10 @@ packages: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} + yoctocolors@1.0.0: + resolution: {integrity: sha512-qJNAmSF77lWjfRVwCZK3PcKYWrr+55RUQTiXDxXHGbxzf8WuuRgftIB3hqZ5fykjOF/MC62cazsG/2ZDBedOnQ==} + engines: {node: '>=14.16'} + zod-validation-error@3.5.3: resolution: {integrity: sha512-OT5Y8lbUadqVZCsnyFaTQ4/O2mys4tj7PqhdbBCp7McPwvIEKfPtdA6QfPeFQK2/Rz5LgwmAXRJTugBNBi0btw==} engines: {node: '>=18.0.0'} @@ -4312,8 +4378,49 @@ snapshots: '@types/tough-cookie': 4.0.5 tough-cookie: 4.1.4 + '@clerc/core@0.44.0': + dependencies: + '@clerc/utils': 0.44.0(@clerc/core@0.44.0) + defu: 6.1.4 + is-platform: 1.0.0 + lite-emit: 2.3.0 + type-fest: 4.41.0 + type-flag: 3.0.0 + + '@clerc/plugin-completions@0.44.0(@clerc/core@0.44.0)': + dependencies: + '@clerc/core': 0.44.0 + '@clerc/utils': 0.44.0(@clerc/core@0.44.0) + + '@clerc/plugin-help@0.44.0(@clerc/core@0.44.0)': + dependencies: + '@clerc/core': 0.44.0 + '@clerc/utils': 0.44.0(@clerc/core@0.44.0) + '@types/text-table': 0.2.5 + string-width: 6.1.0 + text-table: 0.2.0 + yoctocolors: 1.0.0 + + '@clerc/plugin-version@0.44.0(@clerc/core@0.44.0)': + dependencies: + '@clerc/core': 0.44.0 + '@clerc/utils': 0.44.0(@clerc/core@0.44.0) + + '@clerc/utils@0.44.0(@clerc/core@0.44.0)': + dependencies: + '@clerc/core': 0.44.0 + '@colors/colors@1.5.0': {} + '@content-collections/cli@0.1.7(@content-collections/core@0.10.0(typescript@5.7.3))': + dependencies: + '@clerc/core': 0.44.0 + '@clerc/plugin-completions': 0.44.0(@clerc/core@0.44.0) + '@clerc/plugin-help': 0.44.0(@clerc/core@0.44.0) + '@clerc/plugin-version': 0.44.0(@clerc/core@0.44.0) + '@content-collections/core': 0.10.0(typescript@5.7.3) + '@content-collections/integrations': 0.3.0(@content-collections/core@0.10.0(typescript@5.7.3)) + '@content-collections/core@0.10.0(typescript@5.7.3)': dependencies: '@standard-schema/spec': 1.0.0 @@ -4330,6 +4437,10 @@ snapshots: yaml: 2.8.1 zod: 3.25.76 + '@content-collections/integrations@0.3.0(@content-collections/core@0.10.0(typescript@5.7.3))': + dependencies: + '@content-collections/core': 0.10.0(typescript@5.7.3) + '@content-collections/mdx@0.2.2(@content-collections/core@0.10.0(typescript@5.7.3))(acorn@8.15.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: '@content-collections/core': 0.10.0(typescript@5.7.3) @@ -5409,6 +5520,8 @@ snapshots: '@types/statuses@2.0.6': {} + '@types/text-table@0.2.5': {} + '@types/tough-cookie@4.0.5': {} '@types/unist@2.0.11': {} @@ -5829,6 +5942,8 @@ snapshots: clone: 1.0.4 optional: true + defu@6.1.4: {} + dequal@2.0.3: {} detect-libc@2.0.4: {} @@ -5898,6 +6013,8 @@ snapshots: electron-to-chromium@1.5.208: {} + emoji-regex@10.5.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -6336,6 +6453,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-platform@1.0.0: {} + is-stream@2.0.1: {} isarray@1.0.0: {} @@ -6529,6 +6648,8 @@ snapshots: lines-and-columns@1.2.4: {} + lite-emit@2.3.0: {} + lodash.castarray@4.4.0: {} lodash.isplainobject@4.0.6: {} @@ -7627,6 +7748,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string-width@6.1.0: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 10.5.0 + strip-ansi: 7.1.0 + string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 @@ -7680,6 +7807,8 @@ snapshots: glob: 10.4.5 minimatch: 9.0.5 + text-table@0.2.0: {} + through2@2.0.5: dependencies: readable-stream: 2.3.8 @@ -7745,6 +7874,8 @@ snapshots: type-fest@4.41.0: {} + type-flag@3.0.0: {} + typedarray@0.0.6: {} typescript@5.7.3: {} @@ -8076,6 +8207,8 @@ snapshots: yoctocolors-cjs@2.1.3: {} + yoctocolors@1.0.0: {} + zod-validation-error@3.5.3(zod@3.25.76): dependencies: zod: 3.25.76 From 1e49bd5a4e2eeccac82a12623bcd3e00b0c923cd Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 17:12:33 +0200 Subject: [PATCH 19/40] added small console log for debugging --- app/entry.server.tsx | 1 - app/server/search-index.ts | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/entry.server.tsx b/app/entry.server.tsx index 65743ce..4e466ef 100644 --- a/app/entry.server.tsx +++ b/app/entry.server.tsx @@ -15,7 +15,6 @@ import { preloadContentCollections } from "./utils/load-content" export const streamTimeout = 10000 await preloadContentCollections() - await preloadSearchIndexes() export default async function handleRequest( diff --git a/app/server/search-index.ts b/app/server/search-index.ts index 8390151..ed71e04 100644 --- a/app/server/search-index.ts +++ b/app/server/search-index.ts @@ -26,6 +26,8 @@ async function getSearchIndex(version: Version) { throw new Error(`Search index for version "${version}" could not be retrieved.`) } + // biome-ignore lint/suspicious/noConsole:TODO remove this + console.log({ index }) return index } From cb8a2f3a0366c8ae4d244c6ab2393e1d373cac72 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 17:26:30 +0200 Subject: [PATCH 20/40] added small console log for debugging --- app/server/search-index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/server/search-index.ts b/app/server/search-index.ts index ed71e04..b630745 100644 --- a/app/server/search-index.ts +++ b/app/server/search-index.ts @@ -13,7 +13,11 @@ export async function preloadSearchIndexes() { versions.map(async (version) => { if (!searchIndexes.has(version)) { const { allPages } = await loadContentCollections(version) + // biome-ignore lint/suspicious/noConsole:TODO remove this + console.log({ version, allPages }) const searchIndex = createSearchIndex(allPages) + // biome-ignore lint/suspicious/noConsole:TODO remove this + console.log({ searchIndex }) searchIndexes.set(version, searchIndex) } }) From e225d77cb2cb72abb51e8cc815752468bde5852d Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 17:44:05 +0200 Subject: [PATCH 21/40] added small console log for debugging --- app/server/search-index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/server/search-index.ts b/app/server/search-index.ts index b630745..baa5a25 100644 --- a/app/server/search-index.ts +++ b/app/server/search-index.ts @@ -13,8 +13,6 @@ export async function preloadSearchIndexes() { versions.map(async (version) => { if (!searchIndexes.has(version)) { const { allPages } = await loadContentCollections(version) - // biome-ignore lint/suspicious/noConsole:TODO remove this - console.log({ version, allPages }) const searchIndex = createSearchIndex(allPages) // biome-ignore lint/suspicious/noConsole:TODO remove this console.log({ searchIndex }) From 1f1f090438239a913fdb5834ff1f8a6d006a97b4 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 17:49:06 +0200 Subject: [PATCH 22/40] added small console log for debugging and pr-close workflow --- .github/workflows/pr-close.yml | 27 +++++++++++++++++++++++++++ app/server/search-index.ts | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 .github/workflows/pr-close.yml diff --git a/.github/workflows/pr-close.yml b/.github/workflows/pr-close.yml new file mode 100644 index 0000000..1f8f72a --- /dev/null +++ b/.github/workflows/pr-close.yml @@ -0,0 +1,27 @@ +name: 🧹 PR Close + +concurrency: + group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: [main] + types: closed + +jobs: + + destroy-pr-preview: + name: 🧹 Destroy PR Preview + runs-on: ubuntu-latest + environment: + name: pr-preview + steps: + - uses: actions/checkout@v4 + - uses: forge-42/fly-destroy@v1.0.0-rc.2 + id: destroy + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + FLY_ORG: ${{ vars.FLY_ORG }} + with: + app_name: ${{ env.FLY_ORG }}-${{ github.event.number }} diff --git a/app/server/search-index.ts b/app/server/search-index.ts index baa5a25..54a31fd 100644 --- a/app/server/search-index.ts +++ b/app/server/search-index.ts @@ -9,6 +9,8 @@ import { versions } from "~/utils/versions" const searchIndexes: Map = new Map() export async function preloadSearchIndexes() { + // biome-ignore lint/suspicious/noConsole: + console.log("preloading search indexes for versions:", versions) await Promise.all( versions.map(async (version) => { if (!searchIndexes.has(version)) { From 0104233999a9914203e78c2aded220844d38fc02 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 17:59:13 +0200 Subject: [PATCH 23/40] small fix --- app/components/command-k/create-search-index.ts | 3 +-- app/server/search-index.ts | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/app/components/command-k/create-search-index.ts b/app/components/command-k/create-search-index.ts index b102990..bd6997f 100644 --- a/app/components/command-k/create-search-index.ts +++ b/app/components/command-k/create-search-index.ts @@ -108,12 +108,11 @@ function extractHeadingSections(rawMdx: string) { export function createSearchIndex(pages: Page[]) { return pages - .filter((page) => page._meta.fileName === "_index.mdx" && page.slug !== "_index") + .filter((page) => page.slug !== "_index") .flatMap((page) => { const pageSlug = getPageSlug(page) const pageUrl = pageSlug.startsWith("/") ? pageSlug : `/${pageSlug}` const sections = extractHeadingSections(page.rawMdx) - return sections.map((section) => { const heading = section.heading === "_intro" ? page.title : section.heading diff --git a/app/server/search-index.ts b/app/server/search-index.ts index 54a31fd..e1296b8 100644 --- a/app/server/search-index.ts +++ b/app/server/search-index.ts @@ -9,15 +9,12 @@ import { versions } from "~/utils/versions" const searchIndexes: Map = new Map() export async function preloadSearchIndexes() { - // biome-ignore lint/suspicious/noConsole: - console.log("preloading search indexes for versions:", versions) await Promise.all( versions.map(async (version) => { if (!searchIndexes.has(version)) { const { allPages } = await loadContentCollections(version) const searchIndex = createSearchIndex(allPages) - // biome-ignore lint/suspicious/noConsole:TODO remove this - console.log({ searchIndex }) + searchIndexes.set(version, searchIndex) } }) @@ -30,8 +27,6 @@ async function getSearchIndex(version: Version) { throw new Error(`Search index for version "${version}" could not be retrieved.`) } - // biome-ignore lint/suspicious/noConsole:TODO remove this - console.log({ index }) return index } From eec49e9f5515cfde52182c492f1cea16a9c09a09 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 18:02:42 +0200 Subject: [PATCH 24/40] updated env_vars in ci.yml --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8023d20..72dc329 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,6 @@ jobs: app_name: ${{ env.FLY_ORG }}-${{ github.event.number }} env_vars: | APP_ENV=staging - GITHUB_OWNER=forge-42 - GITHUB_REPO=docs-template - GITHUB_REPO_URL=https://github.com/forge-42/docs-template + GITHUB_OWNER=${{github.repository_owner}} + GITHUB_REPO=${{github.event.repository.name}} + GITHUB_REPO_URL=https://github.com/${{ github.repository }} From b649f7bb43dceb12b97e7d851989a6a2031b6c70 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 18:23:29 +0200 Subject: [PATCH 25/40] debounced search --- .../command-k/hooks/use-debounce.ts | 12 +++++++ app/components/command-k/hooks/use-search.ts | 32 +++++++++++-------- 2 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 app/components/command-k/hooks/use-debounce.ts diff --git a/app/components/command-k/hooks/use-debounce.ts b/app/components/command-k/hooks/use-debounce.ts new file mode 100644 index 0000000..1a01372 --- /dev/null +++ b/app/components/command-k/hooks/use-debounce.ts @@ -0,0 +1,12 @@ +import { useEffect, useState } from "react" + +export function useDebounce(value: T, delay = 250) { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const id = setTimeout(() => setDebouncedValue(value), delay) + return () => clearTimeout(id) + }, [value, delay]) + + return debouncedValue +} diff --git a/app/components/command-k/hooks/use-search.ts b/app/components/command-k/hooks/use-search.ts index cd06c74..607b86e 100644 --- a/app/components/command-k/hooks/use-search.ts +++ b/app/components/command-k/hooks/use-search.ts @@ -1,9 +1,10 @@ -import { useState } from "react" +import { useEffect, useRef, useState } from "react" import { useFetcher } from "react-router" import z from "zod" import type { Version } from "~/utils/version-resolvers" import { versions } from "~/utils/versions" import type { SearchResult } from "../search-types" +import { useDebounce } from "./use-debounce" export const commandKSearchParamsSchema = z.object({ query: z.string(), @@ -23,31 +24,36 @@ function createCommandKSearchParams(params: Record) { return { params: new URLSearchParams(result.data) } } +const debounceMs = 250 +const minChars = 1 + export function useSearch({ version }: { version: Version }) { const fetcher = useFetcher<{ results: SearchResult[] }>() const [query, setQuery] = useState("") - //we will show results as soon as we have a non-empty query - //this does not debounce or wait for fetcher.state === "idle". + const debouncedQuery = useDebounce(query, debounceMs) + const lastLoadedRef = useRef(null) + const results = query.trim() ? (fetcher.data?.results ?? []) : [] function search(q: string) { - const trimmed = q.trim() + setQuery(q) + } - if (!trimmed) { - setQuery("") + useEffect(() => { + const trimmed = debouncedQuery.trim() + if (!trimmed || trimmed.length < minChars) { + lastLoadedRef.current = null return } - setQuery(trimmed) + if (lastLoadedRef.current === trimmed) return + lastLoadedRef.current = trimmed + const { params } = createCommandKSearchParams({ query: trimmed, version }) - if (!params) { - // biome-ignore lint/suspicious/noConsole: keep for debugging - console.error("Failed to create search parameters.") - return - } + if (!params) return fetcher.load(`/search?${params.toString()}`) - } + }, [debouncedQuery, version, fetcher]) return { results, From 1e653eeae71769884b86c0b76cd4fa0443321709 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 19:25:07 +0200 Subject: [PATCH 26/40] small update in seo.ts and favion.ico changed --- app/utils/seo.ts | 4 ++-- public/favicon.ico | Bin 16958 -> 15406 bytes ...1200x630.jpg => package-logo-1200x630.jpg} | Bin 3 files changed, 2 insertions(+), 2 deletions(-) rename public/statics/images/{package-image-1200x630.jpg => package-logo-1200x630.jpg} (100%) diff --git a/app/utils/seo.ts b/app/utils/seo.ts index 78199e6..7f2e019 100644 --- a/app/utils/seo.ts +++ b/app/utils/seo.ts @@ -19,11 +19,11 @@ export function generateMetaFields({ domain, title, description, path, additiona title, description, url: fullUrl, - siteName: "Loam", + // Change to your package name + siteName: "Package Name", image: `${image}-1200x630.png`, }, [ - { name: "siteName", content: "Loam.at" }, // Open Graph { property: "og:type", content: "website" }, ...(additionalData ?? []), diff --git a/public/favicon.ico b/public/favicon.ico index 8830cf6821b354114848e6354889b8ecf6d2bc61..4cf2d388ba830b67fa3d4e5cf3b857c8e71468ad 100644 GIT binary patch literal 15406 zcmeHNX>3$g6n;jbl|m`hW|*$ih3QO7p_H~z+R|xfIy2p%tV#v6)Ix;{lt!9@EmlPk zC{&g}0ZGJ#P0H$mQ4&oA6^PL&?kK1Pjets`27i3sbIW^q9p0?q58|EV%bj=MJNGR2 zyYJoHb0p~w=}svuOk%A;s=G^)vL#6}7`m@b10-oX>q}3+e%~lb$0H=k#GYXyOrpD= zHJZOMy>t+``527VM`2=YbdOkCgX1xAKmm$^;xK7oVGqzfb=*4}hGGBeEEM$8;}Jsx zM{CMD9B}@QDdEL1aS7MsDu1dgAB&tuj1SAli-q5yHo6AwBf7YrSuwR}NNiT%=wnj!Pcz5i zyZ4Il<4GH6jAPH`pf;frU5?A#{>rdiY|T5VpfmRboFS=-yggKpn&I(1P@#*$*wAcD z9%zF#$bfsp9SSN!GZk6258}W7Jl1?E_|Zx483Tibf!w**Yf8o`{(d$>T?Iz{fX=N1-*5+`mK|rJ}=Ru{wCux zzJJ+Ue33slFTRmq)1Jm1Xy4ex;}>sRu&gSD$qd4(jJFKhjA)P|R0m>|uN8r}=+5{<05&wsUe4 z@Iq^b!vCY2N8zQ%M<{5t4Q5-{n&ISH2{d7*kj%cL^8N@kB zU>p)_PsB}dKyW~CKyW~CKyW~CKyW~C;P&A_bGZ>m)@5^Snm-gJ1NDBL(=9fw;%CEj zKHN5BlOo%Y(5&>+Jzubtopbxkoz8{BlylSLyYjr|OmI z^HiI6`)b^iw)57yVE#plfOizj9HYVB2If9<>kd zf%yeVC=HL~dDq3Jm5L9PXMLsk7ft)8gxfJQ>H)uS-#sNh$N$*&9K~*V-MVY9eCfd6 z<(VjEHHCIoqxfXnHfHlR#cp|>s^cHX_qWv#{`+G;`9*7+=BlWVj_1*r58H7|?Wb=q z#l}}&t)H8Q*Ef#z3uOQ7?Cu&@s%xNk`kKsx3TR$r{f$Yj=*T?m6>FJ1)mk`1s7~Pa q+4l-t#asyv2o4Ai2o4Ai2o4Ai2o4Ai2o7j*fRzV{pNK%f5%?E*2gYCk literal 16958 zcmeI3+jCXb9mnJN2h^uNlXH@jlam{_a8F3W{T}Wih>9YJpaf7TUbu)A5fv|h7OMfR zR;q$lr&D!wv|c)`wcw1?>4QT1(&|jdsrI2h`Rn)dTW5t$8pz=s3_5L?#oBxAowe8R z_WfPfN?F+@`q$D@rvC?(W!uWieppskmQ~YG*>*L?{img@tWpnYXZslxeh#TSUS3{q z1Ju6JcfQSbQuORq69@YK(X-3c9vC2c2a2z~zw=F=50@pm0PUiCAm!bAT?2jpM`(^b zC|2&Ngngt^<>oCv#?P(AZ`5_84x#QBPulix)TpkIAUp=(KgGo4CVS~Sxt zVoR4>r5g9%bDh7hi0|v$={zr>CHd`?-l4^Ld(Z9PNz9piFY+llUw_x4ou7Vf-q%$g z)&)J4>6Ft~RZ(uV>dJD|`nxI1^x{X@Z5S<=vf;V3w_(*O-7}W<=e$=}CB9_R;)m9)d7`d_xx+nl^Bg|%ew=?uoKO8w zeQU7h;~8s!@9-k>7Cx}1SDQ7m(&miH zs8!l*wOJ!GHbdh)pD--&W3+w`9YJ=;m^FtMY=`mTq8pyV!-@L6smwp3(q?G>=_4v^ zn(ikLue7!y70#2uhqUVpb7fp!=xu2{aM^1P^pts#+feZv8d~)2sf`sjXLQCEj;pdI z%~f`JOO;*KnziMv^i_6+?mL?^wrE_&=IT9o1i!}Sd4Sx4O@w~1bi1)8(sXvYR-1?7~Zr<=SJ1Cw!i~yfi=4h6o3O~(-Sb2Ilwq%g$+V` z>(C&N1!FV5rWF&iwt8~b)=jIn4b!XbrWrZgIHTISrdHcpjjx=TwJXI7_%Ks4oFLl9 zNT;!%!P4~xH85njXdfqgnIxIFOOKW`W$fxU%{{5wZkVF^G=JB$oUNU5dQSL&ZnR1s z*ckJ$R`eCUJsWL>j6*+|2S1TL_J|Fl&kt=~XZF=+=iT0Xq1*KU-NuH%NAQff$LJp3 zU_*a;@7I0K{mqwux87~vwsp<}@P>KNDb}3U+6$rcZ114|QTMUSk+rhPA(b{$>pQTc zIQri{+U>GMzsCy0Mo4BfWXJlkk;RhfpWpAB{=Rtr*d1MNC+H3Oi5+3D$gUI&AjV-1 z=0ZOox+bGyHe=yk-yu%=+{~&46C$ut^ZN+ysx$NH}*F43)3bKkMsxGyIl#>7Yb8W zO{}&LUO8Ow{7>!bvSq?X{15&Y|4}0w2=o_^0ZzYgB+4HhZ4>s*mW&?RQ6&AY|CPcx z$*LjftNS|H)ePYnIKNg{ck*|y7EJ&Co0ho0K`!{ENPkASeKy-JWE}dF_%}j)Z5a&q zXAI2gPu6`s-@baW=*+keiE$ALIs5G6_X_6kgKK8n3jH2-H9`6bo)Qn1 zZ2x)xPt1=`9V|bE4*;j9$X20+xQCc$rEK|9OwH-O+Q*k`ZNw}K##SkY z3u}aCV%V|j@!gL5(*5fuWo>JFjeU9Qqk`$bdwH8(qZovE2tA7WUpoCE=VKm^eZ|vZ z(k<+j*mGJVah>8CkAsMD6#I$RtF;#57Wi`c_^k5?+KCmX$;Ky2*6|Q^bJ8+s%2MB}OH-g$Ev^ zO3uqfGjuN%CZiu<`aCuKCh{kK!dDZ+CcwgIeU2dsDfz+V>V3BDb~)~ zO!2l!_)m;ZepR~sL+-~sHS7;5ZB|~uUM&&5vDda2b z)CW8S6GI*oF><|ZeY5D^+Mcsri)!tmrM33qvwI4r9o@(GlW!u2R>>sB|E#%W`c*@5 z|0iA|`{6aA7D4Q?vc1{vT-#yytn07`H!QIO^1+X7?zG3%y0gPdIPUJ#s*DNAwd}m1_IMN1^T&be~+E z_z%1W^9~dl|Me9U6+3oNyuMDkF*z_;dOG(Baa*yq;TRiw{EO~O_S6>e*L(+Cdu(TM z@o%xTCV%hi&p)x3_inIF!b|W4|AF5p?y1j)cr9RG@v%QVaN8&LaorC-kJz_ExfVHB za!mtuee#Vb?dh&bwrfGHYAiX&&|v$}U*UBM;#F!N=x>x|G5s0zOa9{(`=k4v^6iK3 z8d&=O@xhDs{;v7JQ%eO;!Bt`&*MH&d zp^K#dkq;jnJz%%bsqwlaKA5?fy zS5JDbO#BgSAdi8NM zDo2SifX6^Z;vn>cBh-?~r_n9qYvP|3ihrnqq6deS-#>l#dV4mX|G%L8|EL;$U+w69 z;rTK3FW$ewUfH|R-Z;3;jvpfiDm?Fvyu9PeR>wi|E8>&j2Z@2h`U}|$>2d`BPV3pz#ViIzH8v6pP^L-p!GbLv<;(p>}_6u&E6XO5- zJ8JEvJ1)0>{iSd|kOQn#?0rTYL=KSmgMHCf$Qbm;7|8d(goD&T-~oCDuZf57iP#_Y zmxaoOSjQsm*^u+m$L9AMqwi=6bpdiAY6k3akjGN{xOZ`_J<~Puyzpi7yhhKrLmXV; z@ftONPy;Uw1F#{_fyGbk04yLE01v=i_5`RqQP+SUH0nb=O?l!J)qCSTdsbmjFJrTm zx4^ef@qt{B+TV_OHOhtR?XT}1Etm(f21;#qyyW6FpnM+S7*M1iME?9fe8d-`Q#InN z?^y{C_|8bxgUE@!o+Z72C)BrS&5D`gb-X8kq*1G7Uld-z19V}HY~mK#!o9MC-*#^+ znEsdc-|jj0+%cgBMy(cEkq4IQ1D*b;17Lyp>Utnsz%LRTfjQKL*vo(yJxwtw^)l|! z7jhIDdtLB}mpkOIG&4@F+9cYkS5r%%jz}I0R#F4oBMf-|Jmmk* zk^OEzF%}%5{a~kGYbFjV1n>HKC+a`;&-n*v_kD2DPP~n5(QE3C;30L<32GB*qV2z$ zWR1Kh=^1-q)P37WS6YWKlUSDe=eD^u_CV+P)q!3^{=$#b^auGS7m8zFfFS<>(e~)TG z&uwWhSoetoe!1^%)O}=6{SUcw-UQmw+i8lokRASPsbT=H|4D|( zk^P7>TUEFho!3qXSWn$m2{lHXw zD>eN6-;wwq9(?@f^F4L2Ny5_6!d~iiA^s~(|B*lbZir-$&%)l>%Q(36yOIAu|326K ztmBWz|MLA{Kj(H_{w2gd*nZ6a@ma(w==~EHIscEk|C=NGJa%Ruh4_+~f|%rt{I5v* zIX@F?|KJID56-ivb+PLo(9hn_CdK{irOcL15>JNQFY112^$+}JPyI{uQ~$&E*=ri; z`d^fH?4f=8vKHT4!p9O*fX(brB75Y9?e>T9=X#Fc@V#%@5^)~#zu5I(=>LQA-EGTS zecy*#6gG+8lapch#Hh%vl(+}J;Q!hC1OKoo;#h3#V%5Js)tQ)|>pTT@1ojd+F9Gey zg`B)zm`|Mo%tH31s4=<+`Pu|B3orXwNyIcNN>;fBkIj^X8P}RXhF= zXQK1u5RLN7k#_Q(KznJrALtMM13!vhfr025ar?@-%{l|uWt@NEd<$~n>RQL{ z+o;->n)+~0tt(u|o_9h!T`%M8%)w2awpV9b*xz9Pl-daUJm3y-HT%xg`^mFd6LBeL z!0~s;zEr)Bn9x)I(wx`;JVwvRcc^io2XX(Nn3vr3dgbrr@YJ?K3w18P*52^ieBCQP z=Up1V$N2~5ppJHRTeY8QfM(7Yv&RG7oWJAyv?c3g(29)P)u;_o&w|&)HGDIinXT~p z3;S|e$=&Tek9Wn!`cdY+d-w@o`37}x{(hl>ykB|%9yB$CGdIcl7Z?d&lJ%}QHck77 zJPR%C+s2w1_Dl_pxu6$Zi!`HmoD-%7OD@7%lKLL^Ixd9VlRSW*o&$^iQ2z+}hTgH) z#91TO#+jH<`w4L}XWOt(`gqM*uTUcky`O(mEyU|4dJoy6*UZJ7%*}ajuos%~>&P2j zk23f5<@GeV?(?`l=ih+D8t`d72xrUjv0wsg;%s1@*2p?TQ;n2$pV7h?_T%sL>iL@w zZ{lmc<|B7!e&o!zs6RW+u8+aDyUdG>ZS(v&rT$QVymB7sEC@VsK1dg^3F@K90-wYB zX!we79qx`(6LA>F$~{{xE8-3Wzyfe`+Lsce(?uj{k@lb97YTJt#>l*Z&LyKX@zjmu?UJC9w~;|NsB{%7G}y*uNDBxirfC EKbET!0{{R3 diff --git a/public/statics/images/package-image-1200x630.jpg b/public/statics/images/package-logo-1200x630.jpg similarity index 100% rename from public/statics/images/package-image-1200x630.jpg rename to public/statics/images/package-logo-1200x630.jpg From 849285b7e929656ba4091a2cdfcff40d7194e746 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 19:35:19 +0200 Subject: [PATCH 27/40] added meta for index page --- app/routes/index.tsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/routes/index.tsx b/app/routes/index.tsx index baced90..6ff01a0 100644 --- a/app/routes/index.tsx +++ b/app/routes/index.tsx @@ -2,8 +2,28 @@ import { href, useNavigate } from "react-router" import { Header } from "~/components/header" import { Logo } from "~/components/logo" import { Icon } from "~/ui/icon/icon" +import { getDomain } from "~/utils/get-domain" +import { generateMetaFields } from "~/utils/seo" import { getLatestVersion } from "~/utils/version-resolvers" +import type { Route } from "./+types" +export const meta = ({ data }: Route.MetaArgs) => { + const { domain } = data + + return generateMetaFields({ + domain, + path: "/", + // change "Package Name" to your package name + title: "Package Name", + // update description + description: "Professional Development Made Simple", + }) +} + +export async function loader({ request }: Route.LoaderArgs) { + const { domain } = getDomain(request) + return { domain } +} export default function Index() { const navigate = useNavigate() // Customize index page From fb234fa3b6a02ddee8c32b660e6716dbf42282c2 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 19:37:27 +0200 Subject: [PATCH 28/40] small fix in filename --- ...-logo-1200x630.jpg => package-logo-1200x630.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename public/statics/images/{package-logo-1200x630.jpg => package-logo-1200x630.png} (100%) diff --git a/public/statics/images/package-logo-1200x630.jpg b/public/statics/images/package-logo-1200x630.png similarity index 100% rename from public/statics/images/package-logo-1200x630.jpg rename to public/statics/images/package-logo-1200x630.png From a802352e92ad9035c15d41162fc98113b160b2b6 Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Fri, 12 Sep 2025 19:46:12 +0200 Subject: [PATCH 29/40] fix with seo image? --- app/utils/seo.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/utils/seo.ts b/app/utils/seo.ts index 7f2e019..f8ad034 100644 --- a/app/utils/seo.ts +++ b/app/utils/seo.ts @@ -1,6 +1,6 @@ import { generateMeta } from "@forge42/seo-tools/remix/metadata" import type { MetaDescriptor } from "react-router" -import PackageLogo from "../../public/statics/images/package-logo.png" +import PackageLogo from "../../public/statics/images/package-logo-1200x630.png" interface MetaFields { domain: string @@ -12,7 +12,6 @@ interface MetaFields { export function generateMetaFields({ domain, title, description, path, additionalData }: MetaFields) { const fullUrl = `${domain}${path}` - const image = `${domain}/${PackageLogo}` return generateMeta( { @@ -21,7 +20,7 @@ export function generateMetaFields({ domain, title, description, path, additiona url: fullUrl, // Change to your package name siteName: "Package Name", - image: `${image}-1200x630.png`, + image: PackageLogo, }, [ // Open Graph From 5dbf9386b53ec17dfba062797bec0a58d47bc5ea Mon Sep 17 00:00:00 2001 From: abrulic1 Date: Mon, 15 Sep 2025 12:11:59 +0200 Subject: [PATCH 30/40] small fixes in padding, leading, font size --- app/components/logo.tsx | 2 +- app/components/page-mdx-article.tsx | 2 +- app/components/sidebar/sidebar-items.tsx | 4 ++-- app/routes/index.tsx | 2 +- app/ui/alert.tsx | 15 +++++++++++---- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/components/logo.tsx b/app/components/logo.tsx index 7a6644a..78cf6c2 100644 --- a/app/components/logo.tsx +++ b/app/components/logo.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from "react" export const Logo = ({ children }: { children: ReactNode }) => { return ( -
+
{children}
) diff --git a/app/components/page-mdx-article.tsx b/app/components/page-mdx-article.tsx index 593dc0a..7419032 100644 --- a/app/components/page-mdx-article.tsx +++ b/app/components/page-mdx-article.tsx @@ -4,7 +4,7 @@ import { MDXWrapper } from "./mdx-wrapper" export default function PageMdxArticle({ page }: { page: Page }) { return ( -
+
{page.title} diff --git a/app/components/sidebar/sidebar-items.tsx b/app/components/sidebar/sidebar-items.tsx index 336c55f..392c328 100644 --- a/app/components/sidebar/sidebar-items.tsx +++ b/app/components/sidebar/sidebar-items.tsx @@ -24,7 +24,7 @@ export function DocumentationNavLink({ title, to, depth = 0, onClick }: Document to={to} onClick={onClick} className={({ isActive, isPending }) => - `block rounded-md px-3 py-2 text-xs sm:text-sm md:text-base ${indentClass} + `block rounded-md px-3 py-2 text-sm md:text-base ${indentClass} ${isPending ? "text-[var(--color-text-hover)]" : ""} ${ isActive @@ -46,7 +46,7 @@ interface SectionItemProps { const SectionTitle = ({ title }: { title: string }) => { return ( - <h3 className="mb-3 px-3 font-semibold text-[var(--color-text-active)] text-sm tracking-wide sm:text-base md:text-lg"> + <h3 className="mb-3 px-3 font-semibold text-[var(--color-text-active)] text-base tracking-wide md:text-lg"> {title} </h3> ) diff --git a/app/routes/index.tsx b/app/routes/index.tsx index 6ff01a0..0b89f42 100644 --- a/app/routes/index.tsx +++ b/app/routes/index.tsx @@ -41,7 +41,7 @@ export default function Index() { Version {getLatestVersion()} Now Available </div> - <h1 className="font-bold text-5xl text-[var(--color-text-active)] leading-snug"> + <h1 className="font-bold text-[var(--color-text-active)] text-xl leading-snug md:text-2xl xl:text-3xl"> Professional Development <br /> <span className="bg-gradient-to-r from-[#48ddf3] to-[#fb4bb5] bg-clip-text text-transparent"> diff --git a/app/ui/alert.tsx b/app/ui/alert.tsx index 8b4b0a8..e196583 100644 --- a/app/ui/alert.tsx +++ b/app/ui/alert.tsx @@ -53,13 +53,20 @@ export const Alert = ({ children, title, variant, className = "" }: AlertProps) const defaultTitle = variant === "info" ? t("titles.good_to_know") : t("titles.warning") return ( - <div className={cn("my-6 flex flex-col gap-2 rounded-xl border p-6", styles.container, className)}> - <div className="flex items-center gap-2"> + <div className={cn("my-6 flex flex-col gap-2 rounded-xl border p-4 md:p-6", styles.container, className)}> + <div className="inline-flex items-center gap-2"> <div className={cn("inline-flex", styles.icon)}>{getIcon()}</div> - <p className={cn("font-semibold text-xs sm:text-sm md:text-base", styles.title)}>{title || defaultTitle}</p> + <p className={cn("mt-0 mb-0 font-semibold text-sm md:text-base", styles.title)}>{title || defaultTitle}</p> </div> - <div className={cn("prose prose-xs sm:prose-sm md:prose-base max-w-none", styles.content)}>{children}</div> + <div + className={cn( + "prose prose-xs sm:prose-sm md:prose-base max-w-none text-sm leading-6 sm:text-base md:text-lg", + styles.content + )} + > + {children} + </div> </div> ) } From 5a7a8c8befda1a37e5b0943357b90878607a8c26 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 12:53:06 +0200 Subject: [PATCH 31/40] update in fly.toml, dockerfile and package.json --- Dockerfile | 40 ++++++++++++++++------------------------ fly.toml | 7 ++++++- package.json | 6 +++--- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 00a1d7b..d4769b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,50 +1,42 @@ -# syntax = docker/dockerfile:1 +# syntax = docker/dockerfile:1.4 -# Adjust NODE_VERSION as desired +# Base dependencies stage ARG NODE_VERSION=22.17.0 FROM node:${NODE_VERSION}-slim AS base -LABEL fly_launch_runtime="Node.js" - # Node.js app lives here WORKDIR /app -# Set production environment -ENV NODE_ENV="production" - # Install pnpm -ARG PNPM_VERSION=10.2.0 +ARG PNPM_VERSION=10.13.0 RUN npm install -g pnpm@$PNPM_VERSION - -# Throw-away build stage to reduce size of final image -FROM base AS build - # Install packages needed to build node modules RUN apt-get update -qq && \ apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 git -# Install node modules +# Dependencies stage +FROM base AS dependencies COPY .npmrc package.json pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile --prod=false -# Copy application code +# Build stage +FROM dependencies AS build COPY . . - -# Build application RUN pnpm run generate:docs RUN pnpm run build - -# Remove development dependencies RUN pnpm prune --prod - -# Final stage for app image +# Final production stage FROM base +WORKDIR /app +ENV NODE_ENV=production -# Copy built application -COPY --from=build /app /app +# Copy production dependencies +COPY --from=build /app/node_modules /app/node_modules +COPY --from=build /app/build /app/build +COPY --from=build /app/generated-docs /app/generated-docs -# Start the server by default, this can be overwritten at runtime -EXPOSE 3000 +# Start the server +EXPOSE 8080 CMD [ "pnpm", "run", "start" ] diff --git a/fly.toml b/fly.toml index c9c5d15..fcc93b3 100644 --- a/fly.toml +++ b/fly.toml @@ -8,8 +8,13 @@ primary_region = 'fra' [build] + +[deploy] + strategy = 'bluegreen' + wait_timeout = '15m0s' + [http_service] - internal_port = 3000 + internal_port = 8080 force_https = true auto_stop_machines = 'stop' auto_start_machines = true diff --git a/package.json b/package.json index f5766f0..85cc6f3 100644 --- a/package.json +++ b/package.json @@ -94,13 +94,13 @@ "vitest": "3.0.5", "vitest-browser-react": "0.0.4" }, - "packageManager": "pnpm@10.2.0", + "packageManager": "pnpm@10.13.0", "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "^4.34.3" }, "engines": { - "node": ">=22.11.0", - "pnpm": ">=10.2.0" + "node": ">=22.17.0", + "pnpm": ">=10.13.0" }, "pnpm": { "onlyBuiltDependencies": ["@biomejs/biome", "esbuild", "lefthook", "msw"] From 2b2c5b390fe21e6515f06d48dc09f0e44c999ff8 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 12:57:16 +0200 Subject: [PATCH 32/40] small change in dockerifle --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d4769b5..28d00b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,7 @@ RUN apt-get update -qq && \ # Dependencies stage FROM base AS dependencies COPY .npmrc package.json pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile --prod=false +RUN pnpm install --frozen-lockfile # Build stage FROM dependencies AS build From 2ae70d1f1831722bd24be46d800ee36b3e192b29 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 13:12:33 +0200 Subject: [PATCH 33/40] added http_checks in fly.toml --- fly.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fly.toml b/fly.toml index fcc93b3..aec2c51 100644 --- a/fly.toml +++ b/fly.toml @@ -21,6 +21,15 @@ primary_region = 'fra' min_machines_running = 0 processes = ['app'] + [[services.http_checks]] + interval = '10s' + timeout = '2s' + grace_period = '5s' + method = 'GET' + path = "/" + protocol = 'http' + + [[vm]] memory = '512mb' cpu_kind = 'shared' From 38abb629f41d80546b78e4bdc5dfb2cd6ff0d821 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 13:40:53 +0200 Subject: [PATCH 34/40] small update in fly.toml --- fly.toml | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/fly.toml b/fly.toml index aec2c51..39d5b17 100644 --- a/fly.toml +++ b/fly.toml @@ -1,14 +1,15 @@ -# fly.toml app configuration file generated for docs-template-test on 2025-09-12T12:27:12+02:00 +# fly.toml app configuration file generated for docs-template-test on 2025-09-15T13:34:48+02:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # app = 'docs-template-test' primary_region = 'fra' +kill_signal = 'SIGINT' +kill_timeout = '5s' [build] - [deploy] strategy = 'bluegreen' wait_timeout = '15m0s' @@ -16,21 +17,19 @@ primary_region = 'fra' [http_service] internal_port = 8080 force_https = true - auto_stop_machines = 'stop' + auto_stop_machines = 'suspend' auto_start_machines = true min_machines_running = 0 - processes = ['app'] - - [[services.http_checks]] - interval = '10s' - timeout = '2s' - grace_period = '5s' - method = 'GET' - path = "/" - protocol = 'http' + [[services.http_checks]] + interval = '10s' + timeout = '2s' + grace_period = '5s' + method = 'GET' + path = '/' + protocol = 'http' [[vm]] memory = '512mb' - cpu_kind = 'shared' - cpus = 1 + size = 'shared-cpu-1x' + processes = ['app'] From 40b3f9d570759231e75affc9496f91c6644a69e7 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 13:50:28 +0200 Subject: [PATCH 35/40] small update? --- .github/workflows/ci.yml | 2 +- fly.toml | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72dc329..b979290 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,7 @@ jobs: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} FLY_REGION: ${{ vars.FLY_REGION }} with: - app_name: ${{ env.FLY_ORG }}-${{ github.event.number }} + app_name: ${{github.event.repository.name}}-${{ github.event.number }} env_vars: | APP_ENV=staging GITHUB_OWNER=${{github.repository_owner}} diff --git a/fly.toml b/fly.toml index 39d5b17..78545dd 100644 --- a/fly.toml +++ b/fly.toml @@ -5,8 +5,6 @@ app = 'docs-template-test' primary_region = 'fra' -kill_signal = 'SIGINT' -kill_timeout = '5s' [build] @@ -17,9 +15,10 @@ kill_timeout = '5s' [http_service] internal_port = 8080 force_https = true - auto_stop_machines = 'suspend' + auto_stop_machines = 'stop' auto_start_machines = true min_machines_running = 0 + processes = ['app'] [[services.http_checks]] interval = '10s' @@ -31,5 +30,5 @@ kill_timeout = '5s' [[vm]] memory = '512mb' - size = 'shared-cpu-1x' - processes = ['app'] + cpu_kind = 'shared' + cpus = 1 From 5578c645fa3098d5a58bc129ac95c79bc3aaaabb Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 13:56:26 +0200 Subject: [PATCH 36/40] fly tol update --- fly.toml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/fly.toml b/fly.toml index 78545dd..cbc07fa 100644 --- a/fly.toml +++ b/fly.toml @@ -1,4 +1,4 @@ -# fly.toml app configuration file generated for docs-template-test on 2025-09-15T13:34:48+02:00 +# fly.toml app configuration file generated for docs-template-test on 2025-09-12T12:27:12+02:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # @@ -8,10 +8,6 @@ primary_region = 'fra' [build] -[deploy] - strategy = 'bluegreen' - wait_timeout = '15m0s' - [http_service] internal_port = 8080 force_https = true @@ -20,14 +16,6 @@ primary_region = 'fra' min_machines_running = 0 processes = ['app'] - [[services.http_checks]] - interval = '10s' - timeout = '2s' - grace_period = '5s' - method = 'GET' - path = '/' - protocol = 'http' - [[vm]] memory = '512mb' cpu_kind = 'shared' From 2926f85a908c0767fba397deb328f4e1a54ff7e1 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 14:07:16 +0200 Subject: [PATCH 37/40] previous state? --- Dockerfile | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 28d00b5..e2d0f6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,50 @@ -# syntax = docker/dockerfile:1.4 +# syntax = docker/dockerfile:1 -# Base dependencies stage +# Adjust NODE_VERSION as desired ARG NODE_VERSION=22.17.0 FROM node:${NODE_VERSION}-slim AS base +LABEL fly_launch_runtime="Node.js" + # Node.js app lives here WORKDIR /app +# Set production environment +ENV NODE_ENV="production" + # Install pnpm ARG PNPM_VERSION=10.13.0 RUN npm install -g pnpm@$PNPM_VERSION + +# Throw-away build stage to reduce size of final image +FROM base AS build + # Install packages needed to build node modules RUN apt-get update -qq && \ apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 git -# Dependencies stage -FROM base AS dependencies +# Install node modules COPY .npmrc package.json pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile +RUN pnpm install --frozen-lockfile --prod=false -# Build stage -FROM dependencies AS build +# Copy application code COPY . . + +# Build application RUN pnpm run generate:docs RUN pnpm run build + +# Remove development dependencies RUN pnpm prune --prod -# Final production stage + +# Final stage for app image FROM base -WORKDIR /app -ENV NODE_ENV=production -# Copy production dependencies -COPY --from=build /app/node_modules /app/node_modules -COPY --from=build /app/build /app/build -COPY --from=build /app/generated-docs /app/generated-docs +# Copy built application +COPY --from=build /app /app -# Start the server -EXPOSE 8080 +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 CMD [ "pnpm", "run", "start" ] From 13504f94c180d34e00bfd819ad8eba55f5e7a7a8 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 14:26:55 +0200 Subject: [PATCH 38/40] check? --- Dockerfile | 36 ++++++++++++++++++------------------ fly.toml | 23 ++++++++++++++++++----- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/Dockerfile b/Dockerfile index e2d0f6c..aed099f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,10 @@ -# syntax = docker/dockerfile:1 -# Adjust NODE_VERSION as desired +# syntax = docker/dockerfile:1.4 + +# Base dependencies stage ARG NODE_VERSION=22.17.0 FROM node:${NODE_VERSION}-slim AS base -LABEL fly_launch_runtime="Node.js" - # Node.js app lives here WORKDIR /app @@ -17,34 +16,35 @@ ARG PNPM_VERSION=10.13.0 RUN npm install -g pnpm@$PNPM_VERSION -# Throw-away build stage to reduce size of final image -FROM base AS build - # Install packages needed to build node modules RUN apt-get update -qq && \ apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 git -# Install node modules +# Dependencies stage +FROM base AS dependencies COPY .npmrc package.json pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile --prod=false +RUN pnpm install --frozen-lockfile -# Copy application code +# Build stage +FROM dependencies AS build COPY . . - -# Build application RUN pnpm run generate:docs RUN pnpm run build -# Remove development dependencies + +# Final production stage RUN pnpm prune --prod +FROM base +WORKDIR /app +ENV NODE_ENV=production -# Final stage for app image -FROM base +# Copy production dependencies +COPY --from=build /app/node_modules /app/node_modules +COPY --from=build /app/build /app/build +COPY --from=build /app/generated-docs /app/generated-docs -# Copy built application -COPY --from=build /app /app # Start the server by default, this can be overwritten at runtime -EXPOSE 3000 +EXPOSE 8080 CMD [ "pnpm", "run", "start" ] diff --git a/fly.toml b/fly.toml index cbc07fa..39d5b17 100644 --- a/fly.toml +++ b/fly.toml @@ -1,22 +1,35 @@ -# fly.toml app configuration file generated for docs-template-test on 2025-09-12T12:27:12+02:00 +# fly.toml app configuration file generated for docs-template-test on 2025-09-15T13:34:48+02:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # app = 'docs-template-test' primary_region = 'fra' +kill_signal = 'SIGINT' +kill_timeout = '5s' [build] +[deploy] + strategy = 'bluegreen' + wait_timeout = '15m0s' + [http_service] internal_port = 8080 force_https = true - auto_stop_machines = 'stop' + auto_stop_machines = 'suspend' auto_start_machines = true min_machines_running = 0 - processes = ['app'] + + [[services.http_checks]] + interval = '10s' + timeout = '2s' + grace_period = '5s' + method = 'GET' + path = '/' + protocol = 'http' [[vm]] memory = '512mb' - cpu_kind = 'shared' - cpus = 1 + size = 'shared-cpu-1x' + processes = ['app'] From f68730a983a59d503f3d903428531520da87294a Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Mon, 15 Sep 2025 14:34:12 +0200 Subject: [PATCH 39/40] previous state --- Dockerfile | 31 ++++++++++++++++--------------- fly.toml | 25 ++++++------------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/Dockerfile b/Dockerfile index aed099f..0534ba1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,8 @@ ARG NODE_VERSION=22.17.0 FROM node:${NODE_VERSION}-slim AS base +LABEL fly_launch_runtime="Node.js" + # Node.js app lives here WORKDIR /app @@ -16,35 +18,34 @@ ARG PNPM_VERSION=10.13.0 RUN npm install -g pnpm@$PNPM_VERSION +# Throw-away build stage to reduce size of final image +FROM base AS build + # Install packages needed to build node modules RUN apt-get update -qq && \ apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 git -# Dependencies stage -FROM base AS dependencies +# Install node modules COPY .npmrc package.json pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile +RUN pnpm install --frozen-lockfile --prod=false -# Build stage -FROM dependencies AS build +# Copy application code COPY . . + +# Build application RUN pnpm run generate:docs RUN pnpm run build - -# Final production stage +# Remove development dependencies RUN pnpm prune --prod -FROM base -WORKDIR /app -ENV NODE_ENV=production -# Copy production dependencies -COPY --from=build /app/node_modules /app/node_modules -COPY --from=build /app/build /app/build -COPY --from=build /app/generated-docs /app/generated-docs +# Final stage for app image +FROM base +# Copy built application +COPY --from=build /app /app # Start the server by default, this can be overwritten at runtime -EXPOSE 8080 +EXPOSE 3000 CMD [ "pnpm", "run", "start" ] diff --git a/fly.toml b/fly.toml index 39d5b17..c9c5d15 100644 --- a/fly.toml +++ b/fly.toml @@ -1,35 +1,22 @@ -# fly.toml app configuration file generated for docs-template-test on 2025-09-15T13:34:48+02:00 +# fly.toml app configuration file generated for docs-template-test on 2025-09-12T12:27:12+02:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # app = 'docs-template-test' primary_region = 'fra' -kill_signal = 'SIGINT' -kill_timeout = '5s' [build] -[deploy] - strategy = 'bluegreen' - wait_timeout = '15m0s' - [http_service] - internal_port = 8080 + internal_port = 3000 force_https = true - auto_stop_machines = 'suspend' + auto_stop_machines = 'stop' auto_start_machines = true min_machines_running = 0 - - [[services.http_checks]] - interval = '10s' - timeout = '2s' - grace_period = '5s' - method = 'GET' - path = '/' - protocol = 'http' + processes = ['app'] [[vm]] memory = '512mb' - size = 'shared-cpu-1x' - processes = ['app'] + cpu_kind = 'shared' + cpus = 1 From d2c3788622e64c05d4ddda061d1e464f8d7ed575 Mon Sep 17 00:00:00 2001 From: abrulic1 <abrulic1@etf.unsa.ba> Date: Tue, 16 Sep 2025 10:15:59 +0200 Subject: [PATCH 40/40] small fix --- app/hooks/use-previous-next-pages.ts | 8 ++++---- app/routes/documentation-page.tsx | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/hooks/use-previous-next-pages.ts b/app/hooks/use-previous-next-pages.ts index 7855c06..a90cdbc 100644 --- a/app/hooks/use-previous-next-pages.ts +++ b/app/hooks/use-previous-next-pages.ts @@ -1,6 +1,5 @@ -import type { Page } from "content-collections" import { href, useLocation } from "react-router" -import type { SidebarSection } from "~/components/sidebar/sidebar" +import type { SidebarTree } from "~/utils/create-sidebar-tree" import { flattenSidebarItems } from "~/utils/flatten-sidebar" import { splitSlug } from "~/utils/split-slug" import { useCurrentVersion } from "~/utils/version-resolvers" @@ -20,12 +19,13 @@ function buildDocHref(slug: string, version: string) { }) } -export function usePreviousNextPages(sections: SidebarSection[], standalonePages: Page[] = []) { +export function usePreviousNextPages(sidebarTree: SidebarTree) { const { pathname } = useLocation() const version = useCurrentVersion() + const { sections, documentationPages } = sidebarTree const flatFromSections = flattenSidebarItems(sections) - const flatStandalone = standalonePages.map((p) => ({ title: p.title, slug: p.slug })) + const flatStandalone = documentationPages.map((p) => ({ title: p.title, slug: p.slug })) const flatPages = [...flatStandalone, ...flatFromSections] const currentIndex = flatPages.findIndex((p) => pathname.endsWith(p.slug)) diff --git a/app/routes/documentation-page.tsx b/app/routes/documentation-page.tsx index 95b6989..4339773 100644 --- a/app/routes/documentation-page.tsx +++ b/app/routes/documentation-page.tsx @@ -43,11 +43,10 @@ export async function loader({ params, request }: Route.LoaderArgs) { export default function DocumentationPage({ loaderData }: Route.ComponentProps) { const { page } = loaderData - const { - sidebarTree: { sections, documentationPages }, - } = useDocumentationLayoutLoaderData() - const { previous, next } = usePreviousNextPages(sections, documentationPages) + const { sidebarTree } = useDocumentationLayoutLoaderData() + const { previous, next } = usePreviousNextPages(sidebarTree) const toc = extractHeadingTreeFromMarkdown(page.rawMdx) + return ( <div className="flex min-h-screen flex-row"> <div className="mx-auto flex w-full max-w-screen-4xl flex-col gap-4 pt-4 lg:gap-8 xl:pt-0">