diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml new file mode 100644 index 0000000..22caf16 --- /dev/null +++ b/.github/workflows/canary.yml @@ -0,0 +1,40 @@ +name: canary + +on: + pull_request: + types: [opened, synchronize] + +jobs: + canary-release: + name: Publish canary to npm + runs-on: ubuntu-latest + timeout-minutes: 10 + defaults: + run: + working-directory: ./packages/chronicle + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + + - name: Install dependencies + run: bun install --frozen-lockfile + working-directory: . + + - name: Build CLI + run: bun build-cli.ts + + - name: Set canary version + run: | + SHORT_SHA=$(echo "${{ github.event.pull_request.head.sha }}" | cut -c1-7) + VERSION=$(jq -r .version package.json)-canary.${SHORT_SHA} + jq --arg v "$VERSION" '.version = $v' package.json > package.tmp.json + mv package.tmp.json package.json + echo "Published version: $VERSION" + + - name: Publish + run: bun publish --tag canary --access public + env: + NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index a1b951b..0bf9807 100644 --- a/.gitignore +++ b/.gitignore @@ -135,3 +135,5 @@ dist dist examples/frontier +.claude +.vercel diff --git a/bun.lock b/bun.lock index f1b0c41..3fc5306 100644 --- a/bun.lock +++ b/bun.lock @@ -4,6 +4,13 @@ "workspaces": { "": { "name": "chronicle", + "dependencies": { + "react-router-dom": "^7.13.1", + "satori": "^0.25.0", + }, + "devDependencies": { + "vitest": "^4.1.0", + }, }, "packages/chronicle": { "name": "@raystack/chronicle", @@ -17,27 +24,34 @@ "@codemirror/theme-one-dark": "^6.1.3", "@codemirror/view": "^6.39.14", "@heroicons/react": "^2.2.0", + "@mdx-js/rollup": "^3.1.1", "@raystack/apsara": "^0.56.0", - "@types/unist": "^3.0.3", + "@shikijs/rehype": "^4.0.2", + "@vitejs/plugin-react": "^6.0.1", "chalk": "^5.6.2", "class-variance-authority": "^0.7.1", "codemirror": "^6.0.2", "commander": "^14.0.2", - "fumadocs-core": "16.6.15", - "fumadocs-mdx": "^14.2.6", + "glob": "^11.0.0", + "gray-matter": "^4.0.3", "lodash": "^4.17.23", "mermaid": "^11.13.0", - "next": "16.1.6", + "minisearch": "^7.2.0", + "openapi-types": "^12.1.3", "react": "^19.0.0", - "react-device-detect": "^2.2.3", "react-dom": "^19.0.0", - "remark-attr": "^0.11.1", + "react-router-dom": "^7.13.1", "remark-directive": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.1", + "remark-mdx-frontmatter": "^5.2.0", + "satori": "^0.25.0", + "sirv": "^3.0.1", "slugify": "^1.6.6", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", + "vite": "^8.0.0", "yaml": "^2.8.2", - "zod": "^4.3.6", }, "devDependencies": { "@biomejs/biome": "^2.3.13", @@ -48,7 +62,6 @@ "@types/react": "^19.2.10", "@types/react-dom": "^19.2.3", "@types/semver": "^7.7.1", - "openapi-types": "^12.1.3", "semver": "^7.7.4", "typescript": "5.9.3", }, @@ -113,59 +126,63 @@ "@date-fns/tz": ["@date-fns/tz@1.4.1", "", {}, "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA=="], + "@emnapi/core": ["@emnapi/core@1.9.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w=="], + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], "@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="], @@ -175,65 +192,15 @@ "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], - "@formatjs/fast-memoize": ["@formatjs/fast-memoize@3.1.0", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg=="], - - "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.8.1", "", { "dependencies": { "@formatjs/fast-memoize": "3.1.0", "tslib": "^2.8.1" } }, "sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA=="], - "@heroicons/react": ["@heroicons/react@2.2.0", "", { "peerDependencies": { "react": ">= 16 || ^19.0.0-rc" } }, "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ=="], "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="], - "@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="], - - "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], - - "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], - - "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], - - "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], - - "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], - - "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], - - "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], - - "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], - - "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], - - "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], - - "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], - - "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], - - "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], - - "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], - - "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + "@isaacs/cliui": ["@isaacs/cliui@9.0.0", "", {}, "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg=="], - "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], - - "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], - - "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], - - "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], - - "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], - - "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], - - "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], - - "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], - - "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "@lezer/common": ["@lezer/common@1.5.1", "", {}, "sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw=="], @@ -247,27 +214,17 @@ "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], - "@mermaid-js/parser": ["@mermaid-js/parser@1.0.1", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ=="], - - "@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="], - - "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="], - - "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ=="], + "@mdx-js/rollup": ["@mdx-js/rollup@3.1.1", "", { "dependencies": { "@mdx-js/mdx": "^3.0.0", "@rollup/pluginutils": "^5.0.0", "source-map": "^0.7.0", "vfile": "^6.0.0" }, "peerDependencies": { "rollup": ">=2" } }, "sha512-v8satFmBB+DqDzYohnm1u2JOvxx6Hl3pUvqzJvfs2Zk/ngZ1aRUhsWpXvwPkNeGN9c2NCm/38H29ZqXQUjf8dw=="], - "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw=="], - - "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ=="], - - "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ=="], + "@mermaid-js/parser": ["@mermaid-js/parser@1.0.1", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ=="], - "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], - "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw=="], + "@oxc-project/runtime": ["@oxc-project/runtime@0.115.0", "", {}, "sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ=="], - "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A=="], + "@oxc-project/types": ["@oxc-project/types@0.115.0", "", {}, "sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw=="], - "@orama/orama": ["@orama/orama@3.1.18", "", {}, "sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA=="], + "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], @@ -397,6 +354,90 @@ "@raystack/tools-config": ["@raystack/tools-config@0.56.0", "", { "peerDependencies": { "@biomejs/biome": ">=2.0.0" }, "optionalPeers": ["@biomejs/biome"] }, "sha512-Vh4Ei++2g0hycTFmCF5vjp8VIUasl9TUiQRNv517otYJDY49/C6gqjDt137NDrBRPyguJ+CL+SPY4sRt7UxQxQ=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.9", "", { "os": "android", "cpu": "arm64" }, "sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9", "", { "os": "linux", "cpu": "arm" }, "sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.9", "", { "os": "linux", "cpu": "x64" }, "sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.9", "", { "os": "linux", "cpu": "x64" }, "sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.9", "", { "os": "none", "cpu": "arm64" }, "sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.9", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.9", "", { "os": "win32", "cpu": "x64" }, "sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.7", "", {}, "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA=="], + + "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="], + "@shikijs/core": ["@shikijs/core@4.0.2", "", { "dependencies": { "@shikijs/primitive": "4.0.2", "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw=="], "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag=="], @@ -411,15 +452,13 @@ "@shikijs/themes": ["@shikijs/themes@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2" } }, "sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA=="], - "@shikijs/transformers": ["@shikijs/transformers@4.0.2", "", { "dependencies": { "@shikijs/core": "4.0.2", "@shikijs/types": "4.0.2" } }, "sha512-1+L0gf9v+SdDXs08vjaLb3mBFa8U7u37cwcBQIv/HCocLwX69Tt6LpUCjtB+UUTvQxI7BnjZKhN/wMjhHBcJGg=="], - "@shikijs/types": ["@shikijs/types@4.0.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg=="], "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], - "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + "@shuding/opentype.js": ["@shuding/opentype.js@1.4.0-beta.0", "", { "dependencies": { "fflate": "^0.7.3", "string.prototype.codepointat": "^0.2.1" }, "bin": { "ot": "bin/ot" } }, "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA=="], - "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], "@tanstack/match-sorter-utils": ["@tanstack/match-sorter-utils@8.19.4", "", { "dependencies": { "remove-accents": "0.5.0" } }, "sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg=="], @@ -431,6 +470,10 @@ "@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.18", "", {}, "sha512-Mx86Hqu1k39icq2Zusq+Ey2J6dDWTjDvEv43PJtRCoEYTLyfaPnxIQ6iy7YAOK0NV/qOEmZQ/uCufrppZxTgcg=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + "@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="], "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="], @@ -495,6 +538,8 @@ "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], @@ -529,24 +574,48 @@ "@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="], + "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.1", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.7" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ=="], + + "@vitest/expect": ["@vitest/expect@4.1.0", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.1.0", "@vitest/utils": "4.1.0", "chai": "^6.2.2", "tinyrainbow": "^3.0.3" } }, "sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA=="], + + "@vitest/mocker": ["@vitest/mocker@4.1.0", "", { "dependencies": { "@vitest/spy": "4.1.0", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.0", "", { "dependencies": { "tinyrainbow": "^3.0.3" } }, "sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A=="], + + "@vitest/runner": ["@vitest/runner@4.1.0", "", { "dependencies": { "@vitest/utils": "4.1.0", "pathe": "^2.0.3" } }, "sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ=="], + + "@vitest/snapshot": ["@vitest/snapshot@4.1.0", "", { "dependencies": { "@vitest/pretty-format": "4.1.0", "@vitest/utils": "4.1.0", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg=="], + + "@vitest/spy": ["@vitest/spy@4.1.0", "", {}, "sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw=="], + + "@vitest/utils": ["@vitest/utils@4.1.0", "", { "dependencies": { "@vitest/pretty-format": "4.1.0", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.0.3" } }, "sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw=="], + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], - "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="], + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001770", "", {}, "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw=="], + "base64-js": ["base64-js@0.0.8", "", {}, "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw=="], + + "brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + + "camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], @@ -561,12 +630,8 @@ "chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="], - "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], - "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="], @@ -579,7 +644,7 @@ "color-convert": ["color-convert@3.1.3", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg=="], - "color-name": ["color-name@2.1.0", "", {}, "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg=="], + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], "color-string": ["color-string@2.1.4", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg=="], @@ -587,14 +652,28 @@ "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], - "compute-scroll-into-view": ["compute-scroll-into-view@3.1.1", "", {}, "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw=="], - "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], + "cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="], "crelt": ["crelt@1.0.6", "", {}, "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "css-background-parser": ["css-background-parser@0.1.0", "", {}, "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA=="], + + "css-box-shadow": ["css-box-shadow@1.0.0-3", "", {}, "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg=="], + + "css-color-keywords": ["css-color-keywords@1.0.0", "", {}, "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="], + + "css-gradient-parser": ["css-gradient-parser@0.0.17", "", {}, "sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg=="], + + "css-to-react-native": ["css-to-react-native@3.2.0", "", { "dependencies": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", "postcss-value-parser": "^4.0.2" } }, "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], "cytoscape": ["cytoscape@3.33.1", "", {}, "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ=="], @@ -691,14 +770,22 @@ "dompurify": ["dompurify@3.3.2", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ=="], + "emoji-regex-xs": ["emoji-regex-xs@2.0.1", "", {}, "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g=="], + + "es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], + "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], + "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="], "estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="], @@ -715,17 +802,29 @@ "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], + + "fault": ["fault@2.0.1", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], - "fumadocs-core": ["fumadocs-core@16.6.15", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.8.1", "@orama/orama": "^3.1.18", "@shikijs/rehype": "^4.0.2", "@shikijs/transformers": "^4.0.2", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "^0.46.0", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/estree-jsx": "*", "@types/hast": "*", "@types/mdast": "*", "@types/react": "*", "algoliasearch": "5.x.x", "flexsearch": "*", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "^0.26.0 || ^0.27.0 || ^1.0.0", "zod": "4.x.x" }, "optionalPeers": ["@mdx-js/mdx", "@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/estree-jsx", "@types/hast", "@types/mdast", "@types/react", "algoliasearch", "flexsearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-N6gbXicmaylWeaEFu9vpw25dZK29rPPjalrcIqDRgDklCFkxHn0fsagDMZiSjFBn4RfWRErL6mYmu24WSwosew=="], + "fflate": ["fflate@0.7.4", "", {}, "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw=="], - "fumadocs-mdx": ["fumadocs-mdx@14.2.7", "", { "dependencies": { "@mdx-js/mdx": "^3.1.1", "@standard-schema/spec": "^1.1.0", "chokidar": "^5.0.0", "esbuild": "^0.27.3", "estree-util-value-to-estree": "^3.5.0", "js-yaml": "^4.1.1", "mdast-util-to-markdown": "^2.1.2", "picocolors": "^1.1.1", "picomatch": "^4.0.3", "remark-mdx": "^3.1.1", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3", "zod": "^4.3.6" }, "peerDependencies": { "@fumadocs/mdx-remote": "^1.4.0", "@types/mdast": "*", "@types/mdx": "*", "@types/react": "*", "fumadocs-core": "^15.0.0 || ^16.0.0", "mdast-util-directive": "*", "mdast-util-mdx-jsx": "*", "next": "^15.3.0 || ^16.0.0", "react": "*", "vite": "6.x.x || 7.x.x" }, "optionalPeers": ["@fumadocs/mdx-remote", "@types/mdast", "@types/mdx", "@types/react", "mdast-util-directive", "mdast-util-mdx-jsx", "next", "react", "vite"], "bin": { "fumadocs-mdx": "dist/bin.js" } }, "sha512-Q2W79F7wpwhq4HoYPw9GnMpf5ZmpdU7YzZND7EWwwOiWddfyzPh6EH/z7MFhhdhsTqRh9/kwwsu9XslWDRRPsg=="], + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + + "format": ["format@0.2.2", "", {}, "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], - "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + "glob": ["glob@11.1.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="], + + "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="], "hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="], @@ -739,14 +838,12 @@ "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], - "html-element-attributes": ["html-element-attributes@2.3.0", "", {}, "sha512-RJv2v3BBaYSc0ODHwT0sqWI+2lFs6DATBvCRnW20BDmULxoAWvfT6r28uL8LcW1a9/eqUl+1DccUOJzw00qVXQ=="], + "hex-rgb": ["hex-rgb@4.3.0", "", {}, "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw=="], "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], - "image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="], - "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], @@ -757,42 +854,78 @@ "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], - "is-whitespace-character": ["is-whitespace-character@1.0.4", "", {}, "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], "katex": ["katex@0.16.38", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-cjHooZUmIAUmDsHBN+1n8LaZdpmbj03LtYeYPyuYB7OuloiaeaV6N4LcfjcnHVzGWjVQmKrxxTrpDcmSzEZQwQ=="], "khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="], + "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], + "langium": ["langium@4.2.1", "", { "dependencies": { "chevrotain": "~11.1.1", "chevrotain-allstar": "~0.3.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ=="], "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="], + "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + + "linebreak": ["linebreak@1.1.0", "", { "dependencies": { "base64-js": "0.0.8", "unicode-trie": "^2.0.0" } }, "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ=="], + "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], "lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + "lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], "marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="], - "md-attr-parser": ["md-attr-parser@1.3.0", "", {}, "sha512-KTVlfU5Oxo/6kd0YZ2mLP3eWJj+5vzh5mBCxLo3yGl1fzHIgxmtadbE9tHb7TbUBi3XZbl+P0xKeGmakat135w=="], - "mdast-util-directive": ["mdast-util-directive@3.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q=="], "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="], + "mdast-util-frontmatter": ["mdast-util-frontmatter@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "escape-string-regexp": "^5.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-extension-frontmatter": "^2.0.0" } }, "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA=="], + "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="], @@ -829,6 +962,8 @@ "micromark-extension-directive": ["micromark-extension-directive@4.0.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "parse-entities": "^4.0.0" } }, "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg=="], + "micromark-extension-frontmatter": ["micromark-extension-frontmatter@2.0.0", "", { "dependencies": { "fault": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg=="], + "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="], "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], @@ -895,31 +1030,43 @@ "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + "minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], + + "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="], + "mlly": ["mlly@1.8.1", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ=="], + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - - "next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="], - - "npm-to-yarn": ["npm-to-yarn@3.0.1", "", {}, "sha512-tt6PvKu4WyzPwWUzy/hvPFqn+uwXO0K1ZHka8az3NnrhWJDmSqI8ncWq0fkL0k/lmmi5tAC11FXwXuh0rFbt1A=="], + "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], "oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="], - "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], + "oniguruma-to-es": ["oniguruma-to-es@4.3.5", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ=="], "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + "pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], + + "parse-css-color": ["parse-css-color@0.2.1", "", { "dependencies": { "color-name": "^1.1.4", "hex-rgb": "^4.1.0" } }, "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg=="], + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], "path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="], - "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], @@ -933,7 +1080,9 @@ "points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="], - "postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], "prism-react-renderer": ["prism-react-renderer@2.4.1", "", { "dependencies": { "@types/prismjs": "^1.26.0", "clsx": "^2.0.0" }, "peerDependencies": { "react": ">=16.0.0" } }, "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig=="], @@ -945,17 +1094,17 @@ "react-day-picker": ["react-day-picker@9.13.2", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-IMPiXfXVIAuR5Yk58DDPBC8QKClrhdXV+Tr/alBrwrHUw0qDDYB1m5zPNuTnnPIr/gmJ4ChMxmtqPdxm8+R4Eg=="], - "react-device-detect": ["react-device-detect@2.2.3", "", { "dependencies": { "ua-parser-js": "^1.0.33" }, "peerDependencies": { "react": ">= 0.14.0", "react-dom": ">= 0.14.0" } }, "sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw=="], - "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + "react-router": ["react-router@7.13.1", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA=="], + + "react-router-dom": ["react-router-dom@7.13.1", "", { "dependencies": { "react-router": "7.13.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw=="], - "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="], @@ -973,18 +1122,16 @@ "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], - "remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="], - - "remark-attr": ["remark-attr@0.11.1", "", { "dependencies": { "html-element-attributes": "^2.0.0", "is-whitespace-character": "^1.0.4", "md-attr-parser": "^1.3.0", "remark-footnotes": "^1.0.0" } }, "sha512-NnzURvBJ52c58L3AohBk5qSTBPXdMKsf5+w9L0YNhi/HCtv7ZA9dNRz5NsPIxLtIHhoZIjTqQsMzoyggyPVvkQ=="], - "remark-directive": ["remark-directive@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", "micromark-extension-directive": "^4.0.0", "unified": "^11.0.0" } }, "sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA=="], - "remark-footnotes": ["remark-footnotes@1.0.0", "", {}, "sha512-X9Ncj4cj3/CIvLI2Z9IobHtVi8FVdUrdJkCNaL9kdX8ohfsi18DXHsCVd/A7ssARBdccdDb5ODnt62WuEWaM/g=="], + "remark-frontmatter": ["remark-frontmatter@5.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-frontmatter": "^2.0.0", "micromark-extension-frontmatter": "^2.0.0", "unified": "^11.0.0" } }, "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ=="], "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], "remark-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="], + "remark-mdx-frontmatter": ["remark-mdx-frontmatter@5.2.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "estree-util-value-to-estree": "^3.0.0", "toml": "^3.0.0", "unified": "^11.0.0", "unist-util-mdx-define": "^1.0.0", "yaml": "^2.0.0" } }, "sha512-U/hjUYTkQqNjjMRYyilJgLXSPF65qbLPdoESOkXyrwz2tVyhAnm4GUKhfXqOOS9W34M3545xEMq+aMpHgVjEeQ=="], + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], @@ -995,22 +1142,38 @@ "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="], + "rolldown": ["rolldown@1.0.0-rc.9", "", { "dependencies": { "@oxc-project/types": "=0.115.0", "@rolldown/pluginutils": "1.0.0-rc.9" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.9", "@rolldown/binding-darwin-arm64": "1.0.0-rc.9", "@rolldown/binding-darwin-x64": "1.0.0-rc.9", "@rolldown/binding-freebsd-x64": "1.0.0-rc.9", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.9", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.9", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.9", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.9", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.9", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.9", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.9", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.9" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q=="], + + "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], + "roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="], "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + "satori": ["satori@0.25.0", "", { "dependencies": { "@shuding/opentype.js": "1.4.0-beta.0", "css-background-parser": "^0.1.0", "css-box-shadow": "1.0.0-3", "css-gradient-parser": "^0.0.17", "css-to-react-native": "^3.0.0", "emoji-regex-xs": "^2.0.1", "escape-html": "^1.0.3", "linebreak": "^1.1.0", "parse-css-color": "^0.2.1", "postcss-value-parser": "^4.2.0", "yoga-layout": "^3.2.1" } }, "sha512-utINfLxrYrmSnLvxFT4ZwgwWa8KOjrz7ans32V5wItgHVmzESl/9i33nE38uG0miycab8hUqQtDlOpqrIpB/iw=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - "scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="], + "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], "shiki": ["shiki@4.0.2", "", { "dependencies": { "@shikijs/core": "4.0.2", "@shikijs/engine-javascript": "4.0.2", "@shikijs/engine-oniguruma": "4.0.2", "@shikijs/langs": "4.0.2", "@shikijs/themes": "4.0.2", "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ=="], + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], + "slugify": ["slugify@1.6.6", "", {}, "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw=="], "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="], @@ -1021,22 +1184,40 @@ "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "std-env": ["std-env@4.0.0", "", {}, "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ=="], + + "string.prototype.codepointat": ["string.prototype.codepointat@0.2.1", "", {}, "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="], + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], + "style-mod": ["style-mod@4.1.3", "", {}, "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ=="], "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], - "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], - "stylis": ["stylis@4.3.6", "", {}, "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="], + "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], + + "toml": ["toml@3.0.0", "", {}, "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="], + + "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], @@ -1047,22 +1228,22 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "ua-parser-js": ["ua-parser-js@1.0.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug=="], - "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + "unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="], + "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + "unist-util-mdx-define": ["unist-util-mdx-define@1.1.2", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-9ncH7i7TN5Xn7/tzX5bE3rXgz1X/u877gYVAUB3mLeTKYJmQHmqKTDBi6BTGXV7AeolBCI9ErcVsOt2qryoD0g=="], + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], - "unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="], - "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], @@ -1081,6 +1262,10 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + "vite": ["vite@8.0.0", "", { "dependencies": { "@oxc-project/runtime": "0.115.0", "lightningcss": "^1.32.0", "picomatch": "^4.0.3", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.9", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.0.0-alpha.31", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q=="], + + "vitest": ["vitest@4.1.0", "", { "dependencies": { "@vitest/expect": "4.1.0", "@vitest/mocker": "4.1.0", "@vitest/pretty-format": "4.1.0", "@vitest/runner": "4.1.0", "@vitest/snapshot": "4.1.0", "@vitest/spy": "4.1.0", "@vitest/utils": "4.1.0", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^4.0.0-rc.1", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0-0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.1.0", "@vitest/browser-preview": "4.1.0", "@vitest/browser-webdriverio": "4.1.0", "@vitest/ui": "4.1.0", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw=="], + "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], @@ -1095,9 +1280,13 @@ "w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], - "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], + "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], @@ -1181,6 +1370,12 @@ "@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "color-convert/color-name": ["color-name@2.1.0", "", {}, "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg=="], + + "color-string/color-name": ["color-name@2.1.0", "", {}, "sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg=="], + "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], @@ -1195,6 +1390,10 @@ "radix-ui/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.9", "", {}, "sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw=="], + + "vitest/vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], + "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="], "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], diff --git a/package.json b/package.json index 61028e4..c7736bc 100644 --- a/package.json +++ b/package.json @@ -4,5 +4,12 @@ "workspaces": ["packages/*", "examples/*"], "engines": { "node": ">=22" + }, + "devDependencies": { + "vitest": "^4.1.0" + }, + "dependencies": { + "react-router-dom": "^7.13.1", + "satori": "^0.25.0" } } diff --git a/packages/chronicle/build-cli.ts b/packages/chronicle/build-cli.ts index 2f0a6f7..bd6a723 100644 --- a/packages/chronicle/build-cli.ts +++ b/packages/chronicle/build-cli.ts @@ -1,10 +1,11 @@ -import path from 'path' +import pkg from './package.json' const result = await Bun.build({ entrypoints: ['src/cli/index.ts'], outdir: 'dist/cli', target: 'node', format: 'esm', + external: Object.keys(pkg.dependencies), }) if (!result.success) { diff --git a/packages/chronicle/next.config.mjs b/packages/chronicle/next.config.mjs deleted file mode 100644 index 4b50b92..0000000 --- a/packages/chronicle/next.config.mjs +++ /dev/null @@ -1,10 +0,0 @@ -import { createMDX } from 'fumadocs-mdx/next' - -const withMDX = createMDX() - -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, -} - -export default withMDX(nextConfig) diff --git a/packages/chronicle/package.json b/packages/chronicle/package.json index 6f508a7..1e73e6f 100644 --- a/packages/chronicle/package.json +++ b/packages/chronicle/package.json @@ -9,8 +9,6 @@ "dist", "src", "templates", - "next.config.mjs", - "source.config.ts", "tsconfig.json" ], "bin": { @@ -37,27 +35,34 @@ "@codemirror/theme-one-dark": "^6.1.3", "@codemirror/view": "^6.39.14", "@heroicons/react": "^2.2.0", + "@mdx-js/rollup": "^3.1.1", "@raystack/apsara": "^0.56.0", - "@types/unist": "^3.0.3", + "@vitejs/plugin-react": "^6.0.1", "chalk": "^5.6.2", "class-variance-authority": "^0.7.1", "codemirror": "^6.0.2", "commander": "^14.0.2", - "fumadocs-core": "16.6.15", - "fumadocs-mdx": "^14.2.6", + "glob": "^11.0.0", + "gray-matter": "^4.0.3", "lodash": "^4.17.23", "mermaid": "^11.13.0", - "next": "16.1.6", + "openapi-types": "^12.1.3", "react": "^19.0.0", - "react-device-detect": "^2.2.3", + "react-dom": "^19.0.0", - "remark-attr": "^0.11.1", + "react-router-dom": "^7.13.1", "remark-directive": "^4.0.0", + "remark-gfm": "^4.0.1", + "@shikijs/rehype": "^4.0.2", + "remark-frontmatter": "^5.0.0", + "remark-mdx-frontmatter": "^5.2.0", + "satori": "^0.25.0", + "sirv": "^3.0.1", "slugify": "^1.6.6", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", - "openapi-types": "^12.1.3", - "yaml": "^2.8.2", - "zod": "^4.3.6" + "minisearch": "^7.2.0", + "vite": "^8.0.0", + "yaml": "^2.8.2" } -} \ No newline at end of file +} diff --git a/packages/chronicle/source.config.ts b/packages/chronicle/source.config.ts deleted file mode 100644 index eb8b3ec..0000000 --- a/packages/chronicle/source.config.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { defineDocs, defineConfig, frontmatterSchema } from 'fumadocs-mdx/config' -import { z } from 'zod' -import remarkDirective from 'remark-directive' -import { remarkDirectiveAdmonition, remarkMdxMermaid } from 'fumadocs-core/mdx-plugins' -import remarkUnusedDirectives from './src/lib/remark-unused-directives' - -const contentDir = process.env.CHRONICLE_CONTENT_DIR || './content' - -export const docs = defineDocs({ - dir: contentDir, - docs: { - schema: frontmatterSchema.extend({ - order: z.number().optional(), - lastModified: z.string().optional(), - }), - postprocess: { - includeProcessedMarkdown: true, - }, - files: ['**/*.mdx', '**/*.md', '!**/node_modules/**'], - }, -}) - -export default defineConfig({ - mdxOptions: { - remarkPlugins: [ - remarkDirective, - [ - remarkDirectiveAdmonition, - { - tags: { - CalloutContainer: 'Callout', - CalloutTitle: 'CalloutTitle', - CalloutDescription: 'CalloutDescription', - }, - types: { - note: 'accent', - tip: 'accent', - info: 'accent', - warn: 'attention', - warning: 'attention', - danger: 'alert', - caution: 'alert', - success: 'success', - }, - }, - ], - remarkUnusedDirectives, - remarkMdxMermaid, - ], - }, -}) diff --git a/packages/chronicle/src/app/[[...slug]]/layout.tsx b/packages/chronicle/src/app/[[...slug]]/layout.tsx deleted file mode 100644 index 17b40bf..0000000 --- a/packages/chronicle/src/app/[[...slug]]/layout.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { loadConfig } from '@/lib/config' -import { buildPageTree } from '@/lib/source' -import { getTheme } from '@/themes/registry' - -export default function DocsLayout({ children }: { children: React.ReactNode }) { - const config = loadConfig() - const tree = buildPageTree() - const { Layout, className } = getTheme(config.theme?.name) - - return ( - - {children} - - ) -} diff --git a/packages/chronicle/src/app/[[...slug]]/page.tsx b/packages/chronicle/src/app/[[...slug]]/page.tsx deleted file mode 100644 index c40a615..0000000 --- a/packages/chronicle/src/app/[[...slug]]/page.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import type { Metadata, ResolvingMetadata } from 'next' -import { notFound } from 'next/navigation' -import type { MDXContent } from 'mdx/types' -import { loadConfig } from '@/lib/config' -import { source, buildPageTree } from '@/lib/source' -import { getTheme } from '@/themes/registry' -import { mdxComponents } from '@/components/mdx' - -interface PageProps { - params: Promise<{ slug?: string[] }> -} - -interface PageData { - title: string - description?: string - body: MDXContent - toc: { title: string; url: string; depth: number }[] -} - -export async function generateMetadata( - { params }: PageProps, - parent: ResolvingMetadata, -): Promise { - const { slug } = await params - const page = source.getPage(slug) - if (!page) return {} - const config = loadConfig() - const data = page.data as PageData - const parentMetadata = await parent - - const metadata: Metadata = { - title: data.title, - description: data.description, - } - - if (config.url) { - const ogParams = new URLSearchParams({ title: data.title }) - if (data.description) ogParams.set('description', data.description) - metadata.openGraph = { - ...parentMetadata.openGraph, - title: data.title, - description: data.description, - images: [{ url: `/og?${ogParams.toString()}`, width: 1200, height: 630 }], - } - metadata.twitter = { - ...parentMetadata.twitter, - title: data.title, - description: data.description, - } - } - - return metadata -} - -export default async function DocsPage({ params }: PageProps) { - const { slug } = await params - const config = loadConfig() - - const page = source.getPage(slug) - - if (!page) { - notFound() - } - - const { Page } = getTheme(config.theme?.name) - - const data = page.data as PageData - const MDXBody = data.body - - const tree = buildPageTree() - - const pageUrl = config.url ? `${config.url}/${(slug ?? []).join('/')}` : undefined - - return ( - <> - - , - toc: data.toc ?? [], - }} - config={config} - tree={tree} - /> - - ) -} - -export function generateStaticParams() { - return source.getPages().map((page) => ({ - slug: page.slugs, - })) -} diff --git a/packages/chronicle/src/app/api/apis-proxy/route.ts b/packages/chronicle/src/app/api/apis-proxy/route.ts deleted file mode 100644 index 5ceeb1b..0000000 --- a/packages/chronicle/src/app/api/apis-proxy/route.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { NextRequest, NextResponse } from "next/server"; -import { loadConfig } from "@/lib/config"; -import { loadApiSpecs } from "@/lib/openapi"; - -export async function POST(request: NextRequest) { - const { specName, method, path, headers, body } = await request.json(); - - if (!specName || !method || !path) { - return NextResponse.json( - { error: "Missing specName, method, or path" }, - { status: 400 }, - ); - } - - const config = loadConfig(); - const specs = loadApiSpecs(config.api ?? []); - const spec = specs.find((s) => s.name === specName); - - if (!spec) { - return NextResponse.json( - { error: `Unknown spec: ${specName}` }, - { status: 404 }, - ); - } - - const url = spec.server.url + path; - - try { - const response = await fetch(url, { - method, - headers, - body: body ? JSON.stringify(body) : undefined, - }); - - const contentType = response.headers.get("content-type") ?? ""; - const responseBody = contentType.includes("application/json") - ? await response.json() - : await response.text(); - - return NextResponse.json({ - status: response.status, - statusText: response.statusText, - body: responseBody, - }, { status: response.status }); - } catch (error) { - const message = - error instanceof Error - ? `${error.message}${error.cause ? `: ${(error.cause as Error).message}` : ""}` - : "Request failed"; - return NextResponse.json( - { - status: 502, - statusText: "Bad Gateway", - body: `Could not reach ${url}\n${message}`, - }, - { status: 502 }, - ); - } -} diff --git a/packages/chronicle/src/app/api/search/route.ts b/packages/chronicle/src/app/api/search/route.ts deleted file mode 100644 index 0286227..0000000 --- a/packages/chronicle/src/app/api/search/route.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { source } from '@/lib/source' -import { createSearchAPI, type AdvancedIndex } from 'fumadocs-core/search/server' -import type { StructuredData } from 'fumadocs-core/mdx-plugins' -import type { OpenAPIV3 } from 'openapi-types' -import { loadConfig } from '@/lib/config' -import { loadApiSpecs, type ApiSpec } from '@/lib/openapi' -import { getSpecSlug } from '@/lib/api-routes' - -interface PageData { - title?: string - description?: string - structuredData?: StructuredData - load?: () => Promise<{ structuredData?: StructuredData }> -} - -const HTTP_METHODS = ['get', 'post', 'put', 'delete', 'patch'] as const -type HttpMethod = (typeof HTTP_METHODS)[number] - -function getParamNames(op: OpenAPIV3.OperationObject): string[] { - const params = (op.parameters as OpenAPIV3.ParameterObject[] | undefined) ?? [] - return params.map((p) => p.name) -} - -function buildStructuredData(op: OpenAPIV3.OperationObject, method: string, pathStr: string) { - return { - headings: [{ id: op.operationId!, content: `${method.toUpperCase()} ${pathStr}` }], - contents: [{ heading: op.operationId!, content: `${method.toUpperCase()} ${[op.description, ...getParamNames(op)].filter(Boolean).join(' ')}` }], - } -} - -function operationToIndex(specSlug: string, pathStr: string, method: HttpMethod, op: OpenAPIV3.OperationObject): AdvancedIndex { - const url = `/apis/${specSlug}/${encodeURIComponent(op.operationId!)}` - return { - id: url, - url, - title: `${method.toUpperCase()} ${op.summary ?? op.operationId!}`, - description: op.description ?? '', - structuredData: buildStructuredData(op, method, pathStr), - } -} - -function pathEntryToIndexes(specSlug: string) { - return ([pathStr, pathItem]: [string, OpenAPIV3.PathItemObject | undefined]): AdvancedIndex[] => { - if (!pathItem) return [] - const hasOp = (m: HttpMethod) => !!pathItem[m]?.operationId - const toIndex = (m: HttpMethod) => operationToIndex(specSlug, pathStr, m, pathItem[m]!) - return HTTP_METHODS.filter(hasOp).map(toIndex) - } -} - -function specToIndexes(spec: ApiSpec): AdvancedIndex[] { - const specSlug = getSpecSlug(spec) - return Object.entries(spec.document.paths ?? {}).flatMap(pathEntryToIndexes(specSlug)) -} - -function buildApiIndexes(): AdvancedIndex[] { - const config = loadConfig() - if (!config.api?.length) return [] - return loadApiSpecs(config.api).flatMap(specToIndexes) -} - -export const { GET } = createSearchAPI('advanced', { - indexes: async (): Promise => { - const pages = source.getPages() - const indexes = await Promise.all( - pages.map(async (page): Promise => { - const data = page.data as PageData - let structuredData: StructuredData | undefined = data.structuredData - - if (!structuredData && data.load) { - try { - const loaded = await data.load() - structuredData = loaded.structuredData - } catch (error) { - console.error(`Failed to load structured data for ${page.url}:`, error) - } - } - - return { - id: page.url, - url: page.url, - title: data.title ?? '', - description: data.description ?? '', - structuredData: structuredData ?? { headings: [], contents: [] }, - } - }) - ) - return [...indexes, ...buildApiIndexes()] - }, -}) diff --git a/packages/chronicle/src/app/apis/[[...slug]]/page.tsx b/packages/chronicle/src/app/apis/[[...slug]]/page.tsx deleted file mode 100644 index 8c9c831..0000000 --- a/packages/chronicle/src/app/apis/[[...slug]]/page.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import type { Metadata, ResolvingMetadata } from 'next' -import { notFound } from 'next/navigation' -import type { OpenAPIV3 } from 'openapi-types' -import { Flex, Headline, Text } from '@raystack/apsara' -import { loadConfig } from '@/lib/config' -import { loadApiSpecs } from '@/lib/openapi' -import { buildApiRoutes, findApiOperation } from '@/lib/api-routes' -import { EndpointPage } from '@/components/api' - -interface PageProps { - params: Promise<{ slug?: string[] }> -} - -export async function generateMetadata( - { params }: PageProps, - parent: ResolvingMetadata, -): Promise { - const { slug } = await params - const config = loadConfig() - const specs = loadApiSpecs(config.api ?? []) - const parentMetadata = await parent - - if (!slug || slug.length === 0) { - const apiDescription = `API documentation for ${config.title}` - const metadata: Metadata = { - title: 'API Reference', - description: apiDescription, - } - if (config.url) { - metadata.openGraph = { - ...parentMetadata.openGraph, - title: 'API Reference', - description: apiDescription, - images: [{ url: `/og?title=${encodeURIComponent('API Reference')}&description=${encodeURIComponent(apiDescription)}`, width: 1200, height: 630 }], - } - metadata.twitter = { - ...parentMetadata.twitter, - title: 'API Reference', - description: apiDescription, - } - } - return metadata - } - - const match = findApiOperation(specs, slug) - if (!match) return {} - - const operation = match.operation as OpenAPIV3.OperationObject - const title = operation.summary ?? `${match.method.toUpperCase()} ${match.path}` - const description = operation.description - - const metadata: Metadata = { title, description } - - if (config.url) { - const ogParams = new URLSearchParams({ title }) - if (description) ogParams.set('description', description) - metadata.openGraph = { - ...parentMetadata.openGraph, - title, - description, - images: [{ url: `/og?${ogParams.toString()}`, width: 1200, height: 630 }], - } - metadata.twitter = { - ...parentMetadata.twitter, - title, - description, - } - } - - return metadata -} - -export default async function ApiPage({ params }: PageProps) { - const { slug } = await params - const config = loadConfig() - const specs = loadApiSpecs(config.api ?? []) - - if (!slug || slug.length === 0) { - return - } - - const match = findApiOperation(specs, slug) - if (!match) notFound() - - return ( - - ) -} - -function ApiLanding({ specs }: { specs: { name: string; document: OpenAPIV3.Document }[] }) { - return ( - - API Reference - {specs.map((spec) => ( - - {spec.name} - {spec.document.info.description && ( - {spec.document.info.description} - )} - - ))} - - ) -} - -export function generateStaticParams() { - const config = loadConfig() - const specs = loadApiSpecs(config.api ?? []) - return [{ slug: [] }, ...buildApiRoutes(specs)] -} diff --git a/packages/chronicle/src/app/layout.tsx b/packages/chronicle/src/app/layout.tsx deleted file mode 100644 index c71ed16..0000000 --- a/packages/chronicle/src/app/layout.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import '@raystack/apsara/normalize.css' -import '@raystack/apsara/style.css' -import type { Metadata } from 'next' -import { loadConfig } from '@/lib/config' -import { Providers } from './providers' - -const config = loadConfig() - -export const metadata: Metadata = { - title: { - default: config.title, - template: `%s | ${config.title}`, - }, - description: config.description, - ...(config.url && { - metadataBase: new URL(config.url), - openGraph: { - title: config.title, - description: config.description, - url: config.url, - siteName: config.title, - type: 'website', - images: [{ url: '/og?title=' + encodeURIComponent(config.title), width: 1200, height: 630 }], - }, - twitter: { - card: 'summary_large_image', - title: config.title, - description: config.description, - images: ['/og?title=' + encodeURIComponent(config.title)], - }, - }), -} - -export default function RootLayout({ - children, -}: { - children: React.ReactNode -}) { - return ( - - - {config.url && ( - - )} - {children} - - - ) -} diff --git a/packages/chronicle/src/app/llms-full.txt/route.ts b/packages/chronicle/src/app/llms-full.txt/route.ts deleted file mode 100644 index beb9c70..0000000 --- a/packages/chronicle/src/app/llms-full.txt/route.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { source } from '@/lib/source' -import { loadConfig } from '@/lib/config' -import { getLLMText } from '@/lib/get-llm-text' - -export const revalidate = false - -export async function GET() { - const config = loadConfig() - - if (!config.llms?.enabled) { - return new Response('Not Found', { status: 404 }) - } - - const scan = source.getPages().map(getLLMText) - const scanned = await Promise.all(scan) - - return new Response(scanned.join('\n\n')) -} diff --git a/packages/chronicle/src/app/llms.txt/route.ts b/packages/chronicle/src/app/llms.txt/route.ts deleted file mode 100644 index 664c6cf..0000000 --- a/packages/chronicle/src/app/llms.txt/route.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { source } from '@/lib/source' -import { loadConfig } from '@/lib/config' -import { llms } from 'fumadocs-core/source' - -export const revalidate = false - -export function GET() { - const config = loadConfig() - - if (!config.llms?.enabled) { - return new Response('Not Found', { status: 404 }) - } - - return new Response(llms(source).index()) -} diff --git a/packages/chronicle/src/app/og/route.tsx b/packages/chronicle/src/app/og/route.tsx deleted file mode 100644 index cef9a6f..0000000 --- a/packages/chronicle/src/app/og/route.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { ImageResponse } from 'next/og' -import type { NextRequest } from 'next/server' -import { loadConfig } from '@/lib/config' - -export async function GET(request: NextRequest) { - const { searchParams } = request.nextUrl - const title = searchParams.get('title') ?? loadConfig().title - const description = searchParams.get('description') ?? '' - const siteName = loadConfig().title - - return new ImageResponse( - ( -
-
- {siteName} -
-
- {title} -
- {description && ( -
- {description} -
- )} -
- ), - { - width: 1200, - height: 630, - } - ) -} diff --git a/packages/chronicle/src/app/providers.tsx b/packages/chronicle/src/app/providers.tsx deleted file mode 100644 index 389b797..0000000 --- a/packages/chronicle/src/app/providers.tsx +++ /dev/null @@ -1,8 +0,0 @@ -'use client' - -import { ThemeProvider } from '@raystack/apsara' -import type { ReactNode } from 'react' - -export function Providers({ children }: { children: ReactNode }) { - return {children} -} diff --git a/packages/chronicle/src/app/robots.ts b/packages/chronicle/src/app/robots.ts deleted file mode 100644 index 9b43e68..0000000 --- a/packages/chronicle/src/app/robots.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { MetadataRoute } from 'next' -import { loadConfig } from '@/lib/config' - -export default function robots(): MetadataRoute.Robots { - const config = loadConfig() - return { - rules: { userAgent: '*', allow: '/' }, - ...(config.url && { sitemap: `${config.url}/sitemap.xml` }), - } -} diff --git a/packages/chronicle/src/app/sitemap.ts b/packages/chronicle/src/app/sitemap.ts deleted file mode 100644 index 4da7cdf..0000000 --- a/packages/chronicle/src/app/sitemap.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { MetadataRoute } from 'next' -import { loadConfig } from '@/lib/config' -import { source } from '@/lib/source' -import { loadApiSpecs } from '@/lib/openapi' -import { buildApiRoutes } from '@/lib/api-routes' - -export default function sitemap(): MetadataRoute.Sitemap { - const config = loadConfig() - if (!config.url) return [] - - const baseUrl = config.url.replace(/\/$/, '') - - const docPages = source.getPages().map((page) => ({ - url: `${baseUrl}/${page.slugs.join('/')}`, - ...(page.data.lastModified && { lastModified: new Date(page.data.lastModified) }), - })) - - const apiPages = config.api?.length - ? buildApiRoutes(loadApiSpecs(config.api)).map((route) => ({ - url: `${baseUrl}/apis/${route.slug.join('/')}`, - })) - : [] - - return [ - { url: baseUrl }, - ...docPages, - ...apiPages, - ] -} diff --git a/packages/chronicle/src/cli/__tests__/config.test.ts b/packages/chronicle/src/cli/__tests__/config.test.ts new file mode 100644 index 0000000..b4e8fed --- /dev/null +++ b/packages/chronicle/src/cli/__tests__/config.test.ts @@ -0,0 +1,25 @@ +import { describe, it, expect } from 'vitest' +import { resolveContentDir } from '../utils/config' + +describe('resolveContentDir', () => { + it('returns flag value when provided', () => { + const result = resolveContentDir('/custom/path') + expect(result).toBe('/custom/path') + }) + + it('returns env var when set', () => { + const original = process.env.CHRONICLE_CONTENT_DIR + process.env.CHRONICLE_CONTENT_DIR = '/env/content' + const result = resolveContentDir() + expect(result).toContain('env/content') + process.env.CHRONICLE_CONTENT_DIR = original + }) + + it('defaults to content directory', () => { + const original = process.env.CHRONICLE_CONTENT_DIR + delete process.env.CHRONICLE_CONTENT_DIR + const result = resolveContentDir() + expect(result).toContain('content') + process.env.CHRONICLE_CONTENT_DIR = original + }) +}) diff --git a/packages/chronicle/src/cli/__tests__/scaffold.test.ts b/packages/chronicle/src/cli/__tests__/scaffold.test.ts new file mode 100644 index 0000000..8aa3281 --- /dev/null +++ b/packages/chronicle/src/cli/__tests__/scaffold.test.ts @@ -0,0 +1,10 @@ +import { describe, it, expect } from 'vitest' +import { detectPackageManager } from '../utils/scaffold' + +describe('detectPackageManager', () => { + it('returns a string', () => { + const result = detectPackageManager() + expect(typeof result).toBe('string') + expect(['npm', 'bun', 'pnpm', 'yarn']).toContain(result) + }) +}) diff --git a/packages/chronicle/src/cli/commands/build.ts b/packages/chronicle/src/cli/commands/build.ts index 7ff457c..b281032 100644 --- a/packages/chronicle/src/cli/commands/build.ts +++ b/packages/chronicle/src/cli/commands/build.ts @@ -1,38 +1,80 @@ import { Command } from 'commander' -import { spawn } from 'child_process' import path from 'path' -import fs from 'fs' import chalk from 'chalk' -import { attachLifecycleHandlers, resolveNextCli } from '@/cli/utils' +import { resolveContentDir } from '@/cli/utils/config' +import { PACKAGE_ROOT } from '@/cli/utils/resolve' export const buildCommand = new Command('build') .description('Build for production') - .action(() => { - const scaffoldPath = path.join(process.cwd(), '.chronicle') - if (!fs.existsSync(scaffoldPath)) { - console.log(chalk.red('Error: .chronicle/ not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } + .option('-c, --content ', 'Content directory') + .option('-o, --outDir ', 'Output directory', 'dist') + .option('--adapter ', 'Deploy adapter (vercel)') + .action(async (options) => { + const contentDir = resolveContentDir(options.content) + const outDir = path.resolve(options.outDir) - let nextCli: string - try { - nextCli = resolveNextCli() - } catch { - console.log(chalk.red('Error: Next.js CLI not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) + const VALID_ADAPTERS = ['vercel'] + if (options.adapter && !VALID_ADAPTERS.includes(options.adapter)) { + console.error(chalk.red(`Unknown adapter: ${options.adapter}. Valid adapters: ${VALID_ADAPTERS.join(', ')}`)) process.exit(1) } + process.env.CHRONICLE_PROJECT_ROOT = process.cwd() + process.env.CHRONICLE_CONTENT_DIR = contentDir + console.log(chalk.cyan('Building for production...')) - const child = spawn(process.execPath, [nextCli, 'build'], { - stdio: 'inherit', - cwd: scaffoldPath, - env: { - ...process.env, - CHRONICLE_PROJECT_ROOT: process.cwd(), - CHRONICLE_CONTENT_DIR: './content', + const { build } = await import('vite') + const { createViteConfig } = await import('@/server/vite-config') + + const baseConfig = await createViteConfig({ root: PACKAGE_ROOT, contentDir }) + + // Build client bundle + console.log(chalk.gray('Building client...')) + await build({ + ...baseConfig, + build: { + outDir: path.join(outDir, 'client'), + ssrManifest: true, + rolldownOptions: { + input: path.resolve(PACKAGE_ROOT, 'src/server/index.html'), + }, }, }) - attachLifecycleHandlers(child) + // Build server bundle + const serverEntry = options.adapter === 'vercel' + ? path.resolve(PACKAGE_ROOT, 'src/server/entry-vercel.ts') + : path.resolve(PACKAGE_ROOT, 'src/server/entry-prod.ts') + + console.log(chalk.gray('Building server...')) + await build({ + ...baseConfig, + ssr: { + noExternal: true, + }, + build: { + outDir: path.join(outDir, 'server'), + ssr: serverEntry, + target: 'node22', + }, + }) + + // Generate search index + console.log(chalk.gray('Building search index...')) + const { generateSearchIndex } = await import('@/server/build-search-index') + const docCount = await generateSearchIndex(contentDir, path.join(outDir, 'server')) + console.log(chalk.gray(` Indexed ${docCount} documents`)) + + console.log(chalk.green('Build complete →'), outDir) + + // Run Vercel adapter post-build + if (options.adapter === 'vercel') { + const { buildVercelOutput } = await import('@/server/adapters/vercel') + await buildVercelOutput({ + distDir: outDir, + contentDir, + projectRoot: process.cwd(), + }) + } }) diff --git a/packages/chronicle/src/cli/commands/dev.ts b/packages/chronicle/src/cli/commands/dev.ts index 84c6110..19e89d0 100644 --- a/packages/chronicle/src/cli/commands/dev.ts +++ b/packages/chronicle/src/cli/commands/dev.ts @@ -1,39 +1,21 @@ import { Command } from 'commander' -import { spawn } from 'child_process' -import path from 'path' -import fs from 'fs' import chalk from 'chalk' -import { attachLifecycleHandlers, resolveNextCli } from '@/cli/utils' +import { resolveContentDir } from '@/cli/utils/config' +import { PACKAGE_ROOT } from '@/cli/utils/resolve' export const devCommand = new Command('dev') .description('Start development server') .option('-p, --port ', 'Port number', '3000') - .action((options) => { - const scaffoldPath = path.join(process.cwd(), '.chronicle') - if (!fs.existsSync(scaffoldPath)) { - console.log(chalk.red('Error: .chronicle/ not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } + .option('-c, --content ', 'Content directory') + .action(async (options) => { + const contentDir = resolveContentDir(options.content) + const port = parseInt(options.port, 10) - let nextCli: string - try { - nextCli = resolveNextCli() - } catch { - console.log(chalk.red('Error: Next.js CLI not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } + process.env.CHRONICLE_PROJECT_ROOT = process.cwd() + process.env.CHRONICLE_CONTENT_DIR = contentDir console.log(chalk.cyan('Starting dev server...')) - const child = spawn(process.execPath, [nextCli, 'dev', '-p', options.port], { - stdio: 'inherit', - cwd: scaffoldPath, - env: { - ...process.env, - CHRONICLE_PROJECT_ROOT: process.cwd(), - CHRONICLE_CONTENT_DIR: './content', - }, - }) - - attachLifecycleHandlers(child) + const { startDevServer } = await import('@/server/dev') + await startDevServer({ port, root: PACKAGE_ROOT, contentDir }) }) diff --git a/packages/chronicle/src/cli/commands/init.ts b/packages/chronicle/src/cli/commands/init.ts index f79ce1e..66ba538 100644 --- a/packages/chronicle/src/cli/commands/init.ts +++ b/packages/chronicle/src/cli/commands/init.ts @@ -5,8 +5,7 @@ import path from 'path' import chalk from 'chalk' import { stringify } from 'yaml' import type { ChronicleConfig } from '@/types' -import { loadCLIConfig, scaffoldDir, detectPackageManager, getChronicleVersion } from '@/cli/utils' - +import { detectPackageManager, getChronicleVersion } from '@/cli/utils/scaffold' function createConfig(): ChronicleConfig { return { @@ -59,29 +58,27 @@ export const initCommand = new Command('init') const dirName = path.basename(projectDir) || 'docs' const contentDir = path.join(projectDir, options.content) - // Create content directory if it doesn't exist + // Create content directory if (!fs.existsSync(contentDir)) { fs.mkdirSync(contentDir, { recursive: true }) - console.log(chalk.green('✓'), 'Created', contentDir) + console.log(chalk.green('\u2713'), 'Created', contentDir) } - // Create or update package.json in project root + // Create or update package.json const packageJsonPath = path.join(projectDir, 'package.json') if (!fs.existsSync(packageJsonPath)) { fs.writeFileSync(packageJsonPath, JSON.stringify(createPackageJson(dirName), null, 2) + '\n') - console.log(chalk.green('✓'), 'Created', packageJsonPath) + console.log(chalk.green('\u2713'), 'Created', packageJsonPath) } else { const existing = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')) const template = createPackageJson(dirName) let updated = false - // Set type to module if (existing.type !== 'module') { existing.type = 'module' updated = true } - // Merge missing scripts if (!existing.scripts) existing.scripts = {} for (const [key, value] of Object.entries(template.scripts as Record)) { if (!existing.scripts[key]) { @@ -90,7 +87,6 @@ export const initCommand = new Command('init') } } - // Merge missing dependencies if (!existing.dependencies) existing.dependencies = {} for (const [key, value] of Object.entries(template.dependencies as Record)) { if (!existing.dependencies[key]) { @@ -99,7 +95,6 @@ export const initCommand = new Command('init') } } - // Merge missing devDependencies if (!existing.devDependencies) existing.devDependencies = {} for (const [key, value] of Object.entries(template.devDependencies as Record)) { if (!existing.devDependencies[key]) { @@ -110,42 +105,42 @@ export const initCommand = new Command('init') if (updated) { fs.writeFileSync(packageJsonPath, JSON.stringify(existing, null, 2) + '\n') - console.log(chalk.green('✓'), 'Updated', packageJsonPath, 'with missing scripts/deps') + console.log(chalk.green('\u2713'), 'Updated', packageJsonPath) } else { - console.log(chalk.yellow('⚠'), packageJsonPath, 'already has all required entries') + console.log(chalk.yellow('\u26a0'), packageJsonPath, 'already has all required entries') } } - // Create chronicle.yaml in project root + // Create chronicle.yaml const configPath = path.join(projectDir, 'chronicle.yaml') if (!fs.existsSync(configPath)) { fs.writeFileSync(configPath, stringify(createConfig())) - console.log(chalk.green('✓'), 'Created', configPath) + console.log(chalk.green('\u2713'), 'Created', configPath) } else { - console.log(chalk.yellow('⚠'), configPath, 'already exists') + console.log(chalk.yellow('\u26a0'), configPath, 'already exists') } - // Create sample index.mdx only if content dir is empty + // Create sample index.mdx const contentFiles = fs.readdirSync(contentDir) if (contentFiles.length === 0) { const indexPath = path.join(contentDir, 'index.mdx') fs.writeFileSync(indexPath, sampleMdx) - console.log(chalk.green('✓'), 'Created', indexPath) + console.log(chalk.green('\u2713'), 'Created', indexPath) } - // Add entries to .gitignore + // Update .gitignore const gitignorePath = path.join(projectDir, '.gitignore') - const gitignoreEntries = ['.chronicle', 'node_modules', '.next'] + const gitignoreEntries = ['node_modules', 'dist'] if (fs.existsSync(gitignorePath)) { const existing = fs.readFileSync(gitignorePath, 'utf-8') const missing = gitignoreEntries.filter(e => !existing.includes(e)) if (missing.length > 0) { fs.appendFileSync(gitignorePath, `\n${missing.join('\n')}\n`) - console.log(chalk.green('✓'), 'Added', missing.join(', '), 'to .gitignore') + console.log(chalk.green('\u2713'), 'Added', missing.join(', '), 'to .gitignore') } } else { fs.writeFileSync(gitignorePath, `${gitignoreEntries.join('\n')}\n`) - console.log(chalk.green('✓'), 'Created .gitignore') + console.log(chalk.green('\u2713'), 'Created .gitignore') } // Install dependencies @@ -153,11 +148,7 @@ export const initCommand = new Command('init') console.log(chalk.cyan(`\nInstalling dependencies with ${pm}...`)) execSync(`${pm} install`, { cwd: projectDir, stdio: 'inherit' }) - // Scaffold .chronicle/ directory - loadCLIConfig(contentDir) - scaffoldDir(contentDir) - const runCmd = pm === 'npm' ? 'npx' : pm === 'bun' ? 'bunx' : `${pm} dlx` - console.log(chalk.green('\n✓ Chronicle initialized!')) + console.log(chalk.green('\n\u2713 Chronicle initialized!')) console.log('\nRun', chalk.cyan(`${runCmd} chronicle dev`), 'to start development server') }) diff --git a/packages/chronicle/src/cli/commands/serve.ts b/packages/chronicle/src/cli/commands/serve.ts index 77de8b5..f6cab52 100644 --- a/packages/chronicle/src/cli/commands/serve.ts +++ b/packages/chronicle/src/cli/commands/serve.ts @@ -1,59 +1,55 @@ import { Command } from 'commander' -import { spawn } from 'child_process' import path from 'path' -import fs from 'fs' import chalk from 'chalk' -import { attachLifecycleHandlers, resolveNextCli } from '@/cli/utils' +import { resolveContentDir } from '@/cli/utils/config' +import { PACKAGE_ROOT } from '@/cli/utils/resolve' export const serveCommand = new Command('serve') .description('Build and start production server') .option('-p, --port ', 'Port number', '3000') - .action((options) => { - const scaffoldPath = path.join(process.cwd(), '.chronicle') - if (!fs.existsSync(scaffoldPath)) { - console.log(chalk.red('Error: .chronicle/ not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } - - let nextCli: string - try { - nextCli = resolveNextCli() - } catch { - console.log(chalk.red('Error: Next.js CLI not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } - - const env = { - ...process.env, - CHRONICLE_PROJECT_ROOT: process.cwd(), - CHRONICLE_CONTENT_DIR: './content', - } + .option('-c, --content ', 'Content directory') + .option('-o, --outDir ', 'Output directory', 'dist') + .action(async (options) => { + const contentDir = resolveContentDir(options.content) + const port = parseInt(options.port, 10) + const outDir = path.resolve(options.outDir) + process.env.CHRONICLE_PROJECT_ROOT = process.cwd() + process.env.CHRONICLE_CONTENT_DIR = contentDir + + // Build console.log(chalk.cyan('Building for production...')) - const buildChild = spawn(process.execPath, [nextCli, 'build'], { - stdio: 'inherit', - cwd: scaffoldPath, - env, - }) + const { build } = await import('vite') + const { createViteConfig } = await import('@/server/vite-config') - process.once('SIGINT', () => buildChild.kill('SIGINT')) - process.once('SIGTERM', () => buildChild.kill('SIGTERM')) + const baseConfig = await createViteConfig({ root: PACKAGE_ROOT, contentDir }) - buildChild.on('close', (code) => { - if (code !== 0) { - console.log(chalk.red('Build failed')) - process.exit(code ?? 1) - } + await build({ + ...baseConfig, + build: { + outDir: path.join(outDir, 'client'), + ssrManifest: true, + rolldownOptions: { + input: path.resolve(PACKAGE_ROOT, 'src/server/index.html'), + }, + }, + }) - console.log(chalk.cyan('Starting production server...')) + await build({ + ...baseConfig, + ssr: { + noExternal: true, + }, + build: { + outDir: path.join(outDir, 'server'), + ssr: path.resolve(PACKAGE_ROOT, 'src/server/entry-prod.ts'), + }, + }) - const startChild = spawn(process.execPath, [nextCli, 'start', '-p', options.port], { - stdio: 'inherit', - cwd: scaffoldPath, - env, - }) + // Start + console.log(chalk.cyan('Starting production server...')) - attachLifecycleHandlers(startChild) - }) + const { startProdServer } = await import('@/server/prod') + await startProdServer({ port, root: PACKAGE_ROOT, distDir: outDir }) }) diff --git a/packages/chronicle/src/cli/commands/start.ts b/packages/chronicle/src/cli/commands/start.ts index f29d376..cbb0991 100644 --- a/packages/chronicle/src/cli/commands/start.ts +++ b/packages/chronicle/src/cli/commands/start.ts @@ -1,39 +1,24 @@ import { Command } from 'commander' -import { spawn } from 'child_process' import path from 'path' -import fs from 'fs' import chalk from 'chalk' -import { attachLifecycleHandlers, resolveNextCli } from '@/cli/utils' +import { resolveContentDir } from '@/cli/utils/config' +import { PACKAGE_ROOT } from '@/cli/utils/resolve' export const startCommand = new Command('start') .description('Start production server') .option('-p, --port ', 'Port number', '3000') - .action((options) => { - const scaffoldPath = path.join(process.cwd(), '.chronicle') - if (!fs.existsSync(scaffoldPath)) { - console.log(chalk.red('Error: .chronicle/ not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } + .option('-c, --content ', 'Content directory') + .option('-d, --dist ', 'Dist directory', 'dist') + .action(async (options) => { + const contentDir = resolveContentDir(options.content) + const port = parseInt(options.port, 10) + const distDir = path.resolve(options.dist) - let nextCli: string - try { - nextCli = resolveNextCli() - } catch { - console.log(chalk.red('Error: Next.js CLI not found. Run'), chalk.cyan('chronicle init'), chalk.red('first.')) - process.exit(1) - } + process.env.CHRONICLE_PROJECT_ROOT = process.cwd() + process.env.CHRONICLE_CONTENT_DIR = contentDir console.log(chalk.cyan('Starting production server...')) - const child = spawn(process.execPath, [nextCli, 'start', '-p', options.port], { - stdio: 'inherit', - cwd: scaffoldPath, - env: { - ...process.env, - CHRONICLE_PROJECT_ROOT: process.cwd(), - CHRONICLE_CONTENT_DIR: './content', - }, - }) - - attachLifecycleHandlers(child) + const { startProdServer } = await import('@/server/prod') + await startProdServer({ port, root: PACKAGE_ROOT, distDir }) }) diff --git a/packages/chronicle/src/cli/utils/index.ts b/packages/chronicle/src/cli/utils/index.ts index 7b2a393..d6cce61 100644 --- a/packages/chronicle/src/cli/utils/index.ts +++ b/packages/chronicle/src/cli/utils/index.ts @@ -1,3 +1,2 @@ export * from './config' -export * from './process' -export * from './scaffold' +export * from './resolve' diff --git a/packages/chronicle/src/cli/utils/process.ts b/packages/chronicle/src/cli/utils/process.ts deleted file mode 100644 index eda3e09..0000000 --- a/packages/chronicle/src/cli/utils/process.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { ChildProcess } from 'child_process' - -export function attachLifecycleHandlers(child: ChildProcess) { - child.on('close', (code) => process.exit(code ?? 0)) - process.on('SIGINT', () => child.kill('SIGINT')) - process.on('SIGTERM', () => child.kill('SIGTERM')) -} diff --git a/packages/chronicle/src/cli/utils/scaffold.ts b/packages/chronicle/src/cli/utils/scaffold.ts index ed64f27..00d8c38 100644 --- a/packages/chronicle/src/cli/utils/scaffold.ts +++ b/packages/chronicle/src/cli/utils/scaffold.ts @@ -1,33 +1,7 @@ -import { execSync } from 'child_process' -import { createRequire } from 'module' import fs from 'fs' import path from 'path' -import chalk from 'chalk' import { PACKAGE_ROOT } from './resolve' -const COPY_FILES = ['src', 'source.config.ts', 'tsconfig.json'] - -function copyRecursive(src: string, dest: string) { - const stat = fs.statSync(src) - if (stat.isDirectory()) { - fs.mkdirSync(dest, { recursive: true }) - for (const entry of fs.readdirSync(src)) { - copyRecursive(path.join(src, entry), path.join(dest, entry)) - } - } else { - fs.copyFileSync(src, dest) - } -} - -function ensureRemoved(targetPath: string) { - try { - fs.lstatSync(targetPath) - fs.rmSync(targetPath, { recursive: true, force: true }) - } catch { - // nothing exists, proceed - } -} - export function detectPackageManager(): string { if (process.env.npm_config_user_agent) { return process.env.npm_config_user_agent.split('/')[0] @@ -39,99 +13,8 @@ export function detectPackageManager(): string { return 'npm' } -function generateNextConfig(scaffoldPath: string) { - const config = `import { createMDX } from 'fumadocs-mdx/next' - -const withMDX = createMDX() - -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, -} - -export default withMDX(nextConfig) -` - fs.writeFileSync(path.join(scaffoldPath, 'next.config.mjs'), config) -} - -function createPackageJson(): Record { - return { - name: 'chronicle-docs', - private: true, - dependencies: { - '@raystack/chronicle': `^${getChronicleVersion()}`, - }, - devDependencies: { - '@raystack/tools-config': '0.56.0', - 'openapi-types': '^12.1.3', - typescript: '5.9.3', - '@types/react': '^19.2.10', - '@types/node': '^25.1.0', - }, - } -} - -function ensureDeps() { - const cwd = process.cwd() - const cwdPkgJson = path.join(cwd, 'package.json') - const cwdNodeModules = path.join(cwd, 'node_modules') - - if (fs.existsSync(cwdPkgJson) && fs.existsSync(cwdNodeModules)) { - // Case 1: existing project with deps installed - return - } - - // Case 2: no package.json — create in cwd and install - if (!fs.existsSync(cwdPkgJson)) { - fs.writeFileSync(cwdPkgJson, JSON.stringify(createPackageJson(), null, 2) + '\n') - } - - if (!fs.existsSync(cwdNodeModules)) { - const pm = detectPackageManager() - console.log(chalk.cyan(`Installing dependencies with ${pm}...`)) - execSync(`${pm} install`, { cwd, stdio: 'inherit' }) - } -} - export function getChronicleVersion(): string { const pkgPath = path.join(PACKAGE_ROOT, 'package.json') const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) return pkg.version } - -export function resolveNextCli(): string { - const chronicleRequire = createRequire(path.join(PACKAGE_ROOT, 'package.json')) - return chronicleRequire.resolve('next/dist/bin/next') -} - -export function scaffoldDir(contentDir: string): string { - const scaffoldPath = path.join(process.cwd(), '.chronicle') - - // Create .chronicle/ if not exists - if (!fs.existsSync(scaffoldPath)) { - fs.mkdirSync(scaffoldPath, { recursive: true }) - } - - // Copy package files - for (const name of COPY_FILES) { - const src = path.join(PACKAGE_ROOT, name) - const dest = path.join(scaffoldPath, name) - ensureRemoved(dest) - copyRecursive(src, dest) - } - - // Generate next.config.mjs - generateNextConfig(scaffoldPath) - - // Symlink content dir - const contentLink = path.join(scaffoldPath, 'content') - ensureRemoved(contentLink) - fs.symlinkSync(path.resolve(contentDir), contentLink) - - // Ensure dependencies are available - ensureDeps() - - console.log(chalk.gray(`Scaffold: ${scaffoldPath}`)) - - return scaffoldPath -} diff --git a/packages/chronicle/src/components/mdx/code.tsx b/packages/chronicle/src/components/mdx/code.tsx index c977a01..82dd8b9 100644 --- a/packages/chronicle/src/components/mdx/code.tsx +++ b/packages/chronicle/src/components/mdx/code.tsx @@ -1,6 +1,7 @@ 'use client' -import type { ComponentProps } from 'react' +import { type ComponentProps, isValidElement, Children } from 'react' +import { Mermaid } from './mermaid' import styles from './code.module.css' type PreProps = ComponentProps<'pre'> & { @@ -16,6 +17,14 @@ export function MdxCode({ children, className, ...props }: ComponentProps<'code' } export function MdxPre({ children, title, className, ...props }: PreProps) { + // Detect mermaid code blocks + if (isValidElement(children)) { + const childProps = children.props as { className?: string; children?: string } + if (childProps.className?.includes('language-mermaid') && typeof childProps.children === 'string') { + return + } + } + return (
{title &&
{title}
} diff --git a/packages/chronicle/src/components/mdx/details.module.css b/packages/chronicle/src/components/mdx/details.module.css index f79a00a..01f0dd1 100644 --- a/packages/chronicle/src/components/mdx/details.module.css +++ b/packages/chronicle/src/components/mdx/details.module.css @@ -4,32 +4,9 @@ margin: var(--rs-space-5) 0; } -.summary { - padding: var(--rs-space-4) var(--rs-space-5); - cursor: pointer; +.trigger { font-weight: 500; font-size: var(--rs-font-size-small); - color: var(--rs-color-text-base-primary); - background: var(--rs-color-background-base-secondary); - list-style: none; - display: flex; - align-items: center; - gap: var(--rs-space-3); -} - -.summary::-webkit-details-marker { - display: none; -} - -.summary::before { - content: '▶'; - font-size: 10px; - transition: transform 0.2s ease; - color: var(--rs-color-text-base-secondary); -} - -.details[open] > .summary::before { - transform: rotate(90deg); } .content { diff --git a/packages/chronicle/src/components/mdx/details.tsx b/packages/chronicle/src/components/mdx/details.tsx index 2d29ac0..aa98714 100644 --- a/packages/chronicle/src/components/mdx/details.tsx +++ b/packages/chronicle/src/components/mdx/details.tsx @@ -1,9 +1,8 @@ import type { ComponentProps } from 'react' -import styles from './details.module.css' export function MdxDetails({ children, className, ...props }: ComponentProps<'details'>) { return ( -
+
{children}
) @@ -11,7 +10,7 @@ export function MdxDetails({ children, className, ...props }: ComponentProps<'de export function MdxSummary({ children, className, ...props }: ComponentProps<'summary'>) { return ( - + {children} ) diff --git a/packages/chronicle/src/components/mdx/image.tsx b/packages/chronicle/src/components/mdx/image.tsx index fcf511d..a2bdb5b 100644 --- a/packages/chronicle/src/components/mdx/image.tsx +++ b/packages/chronicle/src/components/mdx/image.tsx @@ -1,6 +1,5 @@ 'use client' -import NextImage from 'next/image' import type { ComponentProps } from 'react' type ImageProps = Omit, 'src'> & { @@ -12,27 +11,14 @@ type ImageProps = Omit, 'src'> & { export function Image({ src, alt, width, height, ...props }: ImageProps) { if (!src || typeof src !== 'string') return null - const isExternal = src.startsWith('http://') || src.startsWith('https://') - - if (isExternal) { - return ( - // eslint-disable-next-line @next/next/no-img-element - {alt - ) - } - return ( - ) } diff --git a/packages/chronicle/src/components/mdx/index.tsx b/packages/chronicle/src/components/mdx/index.tsx index b22d73e..0fc8cb8 100644 --- a/packages/chronicle/src/components/mdx/index.tsx +++ b/packages/chronicle/src/components/mdx/index.tsx @@ -1,6 +1,6 @@ import type { MDXComponents } from 'mdx/types' import { Image } from './image' -import { Link } from './link' +import { MdxLink } from './link' import { MdxTable, MdxThead, MdxTbody, MdxTr, MdxTh, MdxTd } from './table' import { MdxPre, MdxCode } from './code' import { MdxDetails, MdxSummary } from './details' @@ -12,7 +12,7 @@ import { Tabs } from '@raystack/apsara' export const mdxComponents: MDXComponents = { p: MdxParagraph, img: Image, - a: Link, + a: MdxLink, table: MdxTable, thead: MdxThead, tbody: MdxTbody, @@ -32,4 +32,4 @@ export const mdxComponents: MDXComponents = { } export { Image } from './image' -export { Link } from './link' +export { MdxLink } from './link' diff --git a/packages/chronicle/src/components/mdx/link.tsx b/packages/chronicle/src/components/mdx/link.tsx index 8193d6f..93f7fa5 100644 --- a/packages/chronicle/src/components/mdx/link.tsx +++ b/packages/chronicle/src/components/mdx/link.tsx @@ -1,12 +1,11 @@ 'use client' -import NextLink from 'next/link' -import { Link as ApsaraLink } from '@raystack/apsara' +import { Link } from 'react-router-dom' import type { ComponentProps } from 'react' type LinkProps = ComponentProps<'a'> -export function Link({ href, children, ...props }: LinkProps) { +export function MdxLink({ href, children, ...props }: LinkProps) { if (!href) { return {children} } @@ -14,25 +13,25 @@ export function Link({ href, children, ...props }: LinkProps) { const isExternal = href.startsWith('http://') || href.startsWith('https://') const isAnchor = href.startsWith('#') - if (isAnchor) { + if (isExternal) { return ( - + {children} - + ) } - if (isExternal) { + if (isAnchor) { return ( - + {children} - + ) } return ( - + {children} - + ) } diff --git a/packages/chronicle/src/components/ui/footer.tsx b/packages/chronicle/src/components/ui/footer.tsx index 0f3c35f..457bd01 100644 --- a/packages/chronicle/src/components/ui/footer.tsx +++ b/packages/chronicle/src/components/ui/footer.tsx @@ -1,4 +1,5 @@ -import { Flex, Link, Text } from "@raystack/apsara"; +import { Link } from "react-router-dom"; +import { Flex, Text } from "@raystack/apsara"; import type { FooterConfig } from "@/types"; import styles from "./footer.module.css"; @@ -18,7 +19,7 @@ export function Footer({ config }: FooterProps) { {config?.links && config.links.length > 0 && ( {config.links.map((link) => ( - + {link.label} ))} diff --git a/packages/chronicle/src/components/ui/search.tsx b/packages/chronicle/src/components/ui/search.tsx index fb56aaa..e5a2f6a 100644 --- a/packages/chronicle/src/components/ui/search.tsx +++ b/packages/chronicle/src/components/ui/search.tsx @@ -1,21 +1,54 @@ "use client"; -import { useState, useEffect, useCallback } from "react"; -import { useRouter } from "next/navigation"; +import { useState, useEffect, useCallback, useRef } from "react"; +import { useNavigate } from "react-router-dom"; import { Button, Command, Dialog, Text } from "@raystack/apsara"; import { cx } from "class-variance-authority"; -import { useDocsSearch } from "fumadocs-core/search/client"; -import type { SortedResult } from "fumadocs-core/search"; import { DocumentIcon, HashtagIcon } from "@heroicons/react/24/outline"; -import { isMacOs } from "react-device-detect"; import { MethodBadge } from "@/components/api/method-badge"; import styles from "./search.module.css"; +interface SearchResult { + id: string; + url: string; + type: "page" | "api"; + content: string; +} + +function useSearch(query: string) { + const [results, setResults] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const timerRef = useRef | null>(null); + + useEffect(() => { + let cancelled = false; + if (timerRef.current) clearTimeout(timerRef.current); + timerRef.current = setTimeout(async () => { + setIsLoading(true); + try { + const params = new URLSearchParams(); + if (query) params.set("query", query); + const res = await fetch(`/api/search?${params}`); + if (!cancelled) setResults(await res.json()); + } catch { + if (!cancelled) setResults([]); + } + if (!cancelled) setIsLoading(false); + }, 100); + return () => { + cancelled = true; + if (timerRef.current) clearTimeout(timerRef.current); + }; + }, [query]); + + return { results, isLoading }; +} + function SearchShortcutKey({ className }: { className?: string }) { - const [key, setKey] = useState("⌘"); + const [key, setKey] = useState("\u2318"); useEffect(() => { - setKey(isMacOs ? "⌘" : "Ctrl"); + setKey(navigator.platform?.startsWith("Mac") ? "\u2318" : "Ctrl"); }, []); return ( @@ -26,26 +59,21 @@ function SearchShortcutKey({ className }: { className?: string }) { } interface SearchProps { - className?: string + className?: string; } export function Search({ className }: SearchProps) { const [open, setOpen] = useState(false); - const router = useRouter(); - - const { search, setSearch, query } = useDocsSearch({ - type: "fetch", - api: "/api/search", - delayMs: 100, - allowEmpty: true, - }); + const navigate = useNavigate(); + const [search, setSearch] = useState(""); + const { results, isLoading } = useSearch(search); const onSelect = useCallback( (url: string) => { setOpen(false); - router.push(url); + navigate(url); }, - [router], + [navigate], ); useEffect(() => { @@ -60,10 +88,6 @@ export function Search({ className }: SearchProps) { return () => document.removeEventListener("keydown", down); }, []); - const results = deduplicateByUrl( - query.data === "empty" ? [] : (query.data ?? []), - ); - return ( <>
@@ -119,7 +143,7 @@ export function Search({ className }: SearchProps) { )} {search.length > 0 && - results.map((result: SortedResult) => ( + results.map((result) => (
{getResultIcon(result)} -
- {result.type === "heading" ? ( - <> - - - - - - - {getPageTitle(result.url)} - - - ) : ( - - - - )} -
+ + {result.content} +
))} @@ -156,51 +166,12 @@ export function Search({ className }: SearchProps) { ); } -function deduplicateByUrl(results: SortedResult[]): SortedResult[] { - const seen = new Set(); - return results.filter((r) => { - const base = r.url.split("#")[0]; - if (seen.has(base)) return false; - seen.add(base); - return true; - }); -} - -const API_METHODS = new Set(["GET", "POST", "PUT", "DELETE", "PATCH"]); - -function extractMethod(content: string): string | null { - const first = content.split(" ")[0]; - return API_METHODS.has(first) ? first : null; -} - -function stripMethod(content: string): string { - const first = content.split(" ")[0]; - return API_METHODS.has(first) ? content.slice(first.length + 1) : content; -} - -function HighlightedText({ html, className }: { html: string; className?: string }) { - return ; -} - -function getResultIcon(result: SortedResult): React.ReactNode { - if (!result.url.startsWith("/apis/")) { - return result.type === "page" ? ( - - ) : ( - - ); +function getResultIcon(result: SearchResult): React.ReactNode { + if (result.type === "api") { + const method = result.content.split(" ")[0]; + return ["GET", "POST", "PUT", "DELETE", "PATCH"].includes(method) + ? + : null; } - const method = extractMethod(result.content); - return method ? : null; -} - -function getPageTitle(url: string): string { - const path = url.split("#")[0]; - const segments = path.split("/").filter(Boolean); - const lastSegment = segments[segments.length - 1]; - if (!lastSegment) return "Home"; - return lastSegment - .split("-") - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(" "); + return ; } diff --git a/packages/chronicle/src/lib/get-llm-text.ts b/packages/chronicle/src/lib/get-llm-text.ts deleted file mode 100644 index ca218b1..0000000 --- a/packages/chronicle/src/lib/get-llm-text.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { source } from '@/lib/source' -import type { InferPageType } from 'fumadocs-core/source' - -export async function getLLMText(page: InferPageType) { - const processed = await page.data.getText('processed') - - return `# ${page.data.title} (${page.url}) - -${processed}` -} diff --git a/packages/chronicle/src/lib/head.tsx b/packages/chronicle/src/lib/head.tsx new file mode 100644 index 0000000..9e0e067 --- /dev/null +++ b/packages/chronicle/src/lib/head.tsx @@ -0,0 +1,45 @@ +import type { ChronicleConfig } from '@/types' + +export interface HeadProps { + title: string + description?: string + config: ChronicleConfig + jsonLd?: Record +} + +export function Head({ title, description, config, jsonLd }: HeadProps) { + const fullTitle = `${title} | ${config.title}` + const ogParams = new URLSearchParams({ title }) + if (description) ogParams.set('description', description) + + return ( + <> + {fullTitle} + {description && } + + {config.url && ( + <> + + {description && } + + + + + + + + + {description && } + + + )} + + {jsonLd && ( + ` + template = template.replace('', `${dataScript}`) + + const { render } = await vite.ssrLoadModule(path.resolve(root, 'src/server/entry-server.tsx')) + + const html = render(url, { config, tree, page: pageData, apiSpecs }) + const finalHtml = template.replace('', html) + + res.setHeader('Content-Type', 'text/html') + res.statusCode = 200 + res.end(finalHtml) + } catch (e) { + vite.ssrFixStacktrace(e as Error) + console.error(e) + res.statusCode = 500 + res.end((e as Error).message) + } + }) + + server.listen(port, () => { + console.log(chalk.cyan(`\n Chronicle dev server running at:`)) + console.log(chalk.green(` http://localhost:${port}\n`)) + }) + + // Graceful shutdown + const shutdown = () => { + vite.close() + server.close() + process.exit(0) + } + process.on('SIGINT', shutdown) + process.on('SIGTERM', shutdown) + + return { server, vite } +} diff --git a/packages/chronicle/src/server/entry-client.tsx b/packages/chronicle/src/server/entry-client.tsx new file mode 100644 index 0000000..9d38353 --- /dev/null +++ b/packages/chronicle/src/server/entry-client.tsx @@ -0,0 +1,74 @@ +import { hydrateRoot } from 'react-dom/client' +import { BrowserRouter } from 'react-router-dom' +import { PageProvider } from '@/lib/page-context' +import { App } from './App' +import { getPage, loadPageComponent, buildPageTree } from '@/lib/source' +import { mdxComponents } from '@/components/mdx' +import type { ChronicleConfig, PageTree } from '@/types' +import type { ApiSpec } from '@/lib/openapi' +import type { ReactNode } from 'react' +import React from 'react' + +interface EmbeddedData { + config: ChronicleConfig + tree: PageTree + slug: string[] + frontmatter: { title: string; description?: string; order?: number } + filePath: string +} + +async function hydrate() { + try { + const embedded: EmbeddedData | undefined = (window as any).__PAGE_DATA__ + + let config: ChronicleConfig = { title: 'Documentation' } + let tree: PageTree = { name: 'root', children: [] } + let page: { slug: string[]; frontmatter: any; content: ReactNode } | null = null + let apiSpecs: ApiSpec[] = [] + + if (embedded) { + config = embedded.config + tree = embedded.tree + + // Fetch API specs if on /apis route + const isApiRoute = window.location.pathname.startsWith('/apis') + if (isApiRoute && config.api?.length) { + try { + const res = await fetch('/api/specs') + apiSpecs = await res.json() + } catch { /* will load on demand */ } + } + + const sourcePage = await getPage(embedded.slug) + if (sourcePage) { + const component = await loadPageComponent(sourcePage) + page = { + slug: embedded.slug, + frontmatter: embedded.frontmatter, + content: component ? React.createElement(component, { components: mdxComponents }) : null, + } + } else { + page = { + slug: embedded.slug, + frontmatter: embedded.frontmatter, + content: null, + } + } + } else { + tree = await buildPageTree() + } + + hydrateRoot( + document.getElementById('root') as HTMLElement, + + + + + , + ) + } catch (err) { + console.error('Hydration failed:', err) + } +} + +hydrate() diff --git a/packages/chronicle/src/server/entry-prod.ts b/packages/chronicle/src/server/entry-prod.ts new file mode 100644 index 0000000..ea32373 --- /dev/null +++ b/packages/chronicle/src/server/entry-prod.ts @@ -0,0 +1,98 @@ +// Production server entry — built by Vite, loaded by prod.ts at runtime +import { createServer } from 'http' +import { readFileSync, createReadStream } from 'fs' +import fsPromises from 'fs/promises' +import path from 'path' +import { render } from './entry-server' +import { matchRoute } from './router' +import { loadConfig } from '@/lib/config' +import { loadApiSpecs } from '@/lib/openapi' +import { getPage, loadPageComponent, buildPageTree } from '@/lib/source' +import { handleRequest } from './request-handler' +import { safePath } from './utils/safe-path' + +export { render, matchRoute, loadConfig, loadApiSpecs, getPage, loadPageComponent, buildPageTree } + +async function writeResponse(res: import('http').ServerResponse, response: Response) { + res.statusCode = response.status + response.headers.forEach((value: string, key: string) => res.setHeader(key, value)) + const body = await response.text() + res.end(body) +} + +export async function startServer(options: { port: number; distDir: string }) { + const { port, distDir } = options + + const clientDir = path.resolve(distDir, 'client') + const templatePath = path.resolve(clientDir, 'src/server/index.html') + const template = readFileSync(templatePath, 'utf-8') + + const sirv = (await import('sirv')).default + const assets = sirv(clientDir, { gzip: true }) + + const baseUrl = `http://localhost:${port}` + + const server = createServer(async (req, res) => { + const url = req.url || '/' + + try { + // API routes — handled by shared request handler + const routeHandler = matchRoute(new URL(url, baseUrl).href) + if (routeHandler) { + const response = await routeHandler(new Request(new URL(url, baseUrl))) + await writeResponse(res, response) + return + } + + // Serve static files from content dir (skip .md/.mdx) + const contentDir = process.env.CHRONICLE_CONTENT_DIR || process.cwd() + const contentFile = safePath(contentDir, url) + if (contentFile && !url.endsWith('.md') && !url.endsWith('.mdx')) { + try { + const stat = await fsPromises.stat(contentFile) + if (stat.isFile()) { + const ext = path.extname(contentFile).toLowerCase() + const mimeTypes: Record = { + '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', + '.gif': 'image/gif', '.svg': 'image/svg+xml', '.webp': 'image/webp', + '.ico': 'image/x-icon', '.pdf': 'application/pdf', '.json': 'application/json', + '.yaml': 'text/yaml', '.yml': 'text/yaml', '.txt': 'text/plain', + } + res.setHeader('Content-Type', mimeTypes[ext] || 'application/octet-stream') + createReadStream(contentFile).pipe(res) + return + } + } catch { /* fall through */ } + } + + // Static assets from dist/client + const assetHandled = await new Promise((resolve) => { + assets(req, res, () => resolve(false)) + res.on('close', () => resolve(true)) + }) + if (assetHandled) return + + // SSR render — handled by shared request handler + const response = await handleRequest(url, { template, baseUrl }) + await writeResponse(res, response) + } catch (e) { + console.error(e) + res.statusCode = 500 + res.end('Internal Server Error') + } + }) + + server.listen(port, () => { + console.log(`\n Chronicle production server running at:`) + console.log(` http://localhost:${port}\n`) + }) + + const shutdown = () => { + server.close() + process.exit(0) + } + process.on('SIGINT', shutdown) + process.on('SIGTERM', shutdown) + + return server +} diff --git a/packages/chronicle/src/server/entry-server.tsx b/packages/chronicle/src/server/entry-server.tsx new file mode 100644 index 0000000..551ea07 --- /dev/null +++ b/packages/chronicle/src/server/entry-server.tsx @@ -0,0 +1,35 @@ +import { renderToString } from 'react-dom/server' +import { StaticRouter } from 'react-router-dom' +import { PageProvider } from '@/lib/page-context' +import { App } from './App' +import type { ReactNode } from 'react' +import type { ChronicleConfig, Frontmatter, PageTree } from '@/types' +import type { ApiSpec } from '@/lib/openapi' + +export interface SSRData { + config: ChronicleConfig + tree: PageTree + page: { + slug: string[] + frontmatter: Frontmatter + content: ReactNode + } | null + apiSpecs: ApiSpec[] +} + +export function render(url: string, data: SSRData): string { + const pathname = new URL(url, 'http://localhost').pathname + + return renderToString( + + + + + , + ) +} diff --git a/packages/chronicle/src/server/entry-vercel.ts b/packages/chronicle/src/server/entry-vercel.ts new file mode 100644 index 0000000..0c58092 --- /dev/null +++ b/packages/chronicle/src/server/entry-vercel.ts @@ -0,0 +1,28 @@ +// Vercel serverless function entry — built by Vite, deployed as catch-all function +import type { IncomingMessage, ServerResponse } from 'http' +import { readFileSync } from 'fs' +import { fileURLToPath } from 'url' +import path from 'path' +import { handleRequest } from './request-handler' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const templatePath = path.resolve(__dirname, 'index.html') +const template = readFileSync(templatePath, 'utf-8') + +export default async function handler(req: IncomingMessage, res: ServerResponse) { + const url = req.url || '/' + const baseUrl = `https://${req.headers.host || 'localhost'}` + + try { + const response = await handleRequest(url, { template, baseUrl }) + + res.statusCode = response.status + response.headers.forEach((value: string, key: string) => res.setHeader(key, value)) + const body = await response.text() + res.end(body) + } catch (e) { + console.error(e) + res.statusCode = 500 + res.end('Internal Server Error') + } +} diff --git a/packages/chronicle/src/server/handlers/apis-proxy.ts b/packages/chronicle/src/server/handlers/apis-proxy.ts new file mode 100644 index 0000000..77fb06f --- /dev/null +++ b/packages/chronicle/src/server/handlers/apis-proxy.ts @@ -0,0 +1,57 @@ +import { loadConfig } from '@/lib/config' +import { loadApiSpecs } from '@/lib/openapi' + +export async function handleApisProxy(req: Request): Promise { + if (req.method !== 'POST') { + return Response.json({ error: 'Method not allowed' }, { status: 405 }) + } + + const { specName, method, path, headers, body } = await req.json() + + if (!specName || !method || !path) { + return Response.json({ error: 'Missing specName, method, or path' }, { status: 400 }) + } + + const config = loadConfig() + const specs = loadApiSpecs(config.api ?? []) + const spec = specs.find((s) => s.name === specName) + + if (!spec) { + return Response.json({ error: `Unknown spec: ${specName}` }, { status: 404 }) + } + + // Validate path doesn't contain protocol or escape the base URL + if (/^[a-z]+:\/\//i.test(path) || path.includes('..')) { + return Response.json({ error: 'Invalid path' }, { status: 400 }) + } + + const url = spec.server.url + path + + try { + const response = await fetch(url, { + method, + headers, + body: body ? JSON.stringify(body) : undefined, + }) + + const contentType = response.headers.get('content-type') ?? '' + const responseBody = contentType.includes('application/json') + ? await response.json() + : await response.text() + + return Response.json({ + status: response.status, + statusText: response.statusText, + body: responseBody, + }, { status: response.status }) + } catch (error) { + const message = error instanceof Error + ? `${error.message}${error.cause ? `: ${(error.cause as Error).message}` : ''}` + : 'Request failed' + return Response.json({ + status: 502, + statusText: 'Bad Gateway', + body: `Could not reach ${url}\n${message}`, + }, { status: 502 }) + } +} diff --git a/packages/chronicle/src/app/api/health/route.ts b/packages/chronicle/src/server/handlers/health.ts similarity index 50% rename from packages/chronicle/src/app/api/health/route.ts rename to packages/chronicle/src/server/handlers/health.ts index 5ebc71e..611693a 100644 --- a/packages/chronicle/src/app/api/health/route.ts +++ b/packages/chronicle/src/server/handlers/health.ts @@ -1,3 +1,3 @@ -export function GET() { +export function handleHealth(): Response { return Response.json({ status: 'ok' }) } diff --git a/packages/chronicle/src/server/handlers/llms.ts b/packages/chronicle/src/server/handlers/llms.ts new file mode 100644 index 0000000..d587b6a --- /dev/null +++ b/packages/chronicle/src/server/handlers/llms.ts @@ -0,0 +1,58 @@ +import fs from 'fs/promises' +import path from 'path' +import matter from 'gray-matter' +import { loadConfig } from '@/lib/config' + +function getContentDir(): string { + return process.env.CHRONICLE_CONTENT_DIR || path.join(process.cwd(), 'content') +} + +async function scanPages(): Promise<{ title: string; url: string }[]> { + const contentDir = getContentDir() + const pages: { title: string; url: string }[] = [] + + async function scan(dir: string, prefix: string[] = []) { + let entries + try { entries = await fs.readdir(dir, { withFileTypes: true }) } + catch { return } + + for (const entry of entries) { + if (entry.name.startsWith('.') || entry.name === 'node_modules') continue + const fullPath = path.join(dir, entry.name) + + if (entry.isDirectory()) { + await scan(fullPath, [...prefix, entry.name]) + continue + } + + if (!entry.name.endsWith('.mdx') && !entry.name.endsWith('.md')) continue + + const raw = await fs.readFile(fullPath, 'utf-8') + const { data: fm } = matter(raw) + const baseName = entry.name.replace(/\.(mdx|md)$/, '') + const slugs = baseName === 'index' ? prefix : [...prefix, baseName] + const url = slugs.length === 0 ? '/' : '/' + slugs.join('/') + + pages.push({ title: fm.title ?? baseName, url }) + } + } + + await scan(contentDir) + return pages +} + +export async function handleLlms(): Promise { + const config = loadConfig() + + if (!config.llms?.enabled) { + return new Response('Not Found', { status: 404 }) + } + + const pages = await scanPages() + const index = pages.map((p) => `- [${p.title}](${p.url})`).join('\n') + const body = `# ${config.title}\n\n${config.description ?? ''}\n\n${index}` + + return new Response(body, { + headers: { 'Content-Type': 'text/plain' }, + }) +} diff --git a/packages/chronicle/src/server/handlers/og.ts b/packages/chronicle/src/server/handlers/og.ts new file mode 100644 index 0000000..ffca945 --- /dev/null +++ b/packages/chronicle/src/server/handlers/og.ts @@ -0,0 +1,87 @@ +import satori from 'satori' +import { loadConfig } from '@/lib/config' + +let fontData: ArrayBuffer | null = null + +async function loadFont(): Promise { + if (fontData) return fontData + + try { + const response = await fetch('https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfAZ9hiA.woff2') + fontData = await response.arrayBuffer() + } catch { + // Fallback: create minimal valid font buffer + fontData = new ArrayBuffer(0) + } + + return fontData +} + +export async function handleOg(req: Request): Promise { + const url = new URL(req.url) + const title = url.searchParams.get('title') ?? loadConfig().title + const description = url.searchParams.get('description') ?? '' + const siteName = loadConfig().title + + const font = await loadFont() + + const svg = await satori( + { + type: 'div', + props: { + style: { + height: '100%', + width: '100%', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + padding: '60px 80px', + backgroundColor: '#0a0a0a', + color: '#fafafa', + }, + children: [ + { + type: 'div', + props: { + style: { fontSize: 24, color: '#888', marginBottom: 16 }, + children: siteName, + }, + }, + { + type: 'div', + props: { + style: { fontSize: 56, fontWeight: 700, lineHeight: 1.2, marginBottom: 24 }, + children: title, + }, + }, + ...(description ? [{ + type: 'div', + props: { + style: { fontSize: 24, color: '#999', lineHeight: 1.4 }, + children: description, + }, + }] : []), + ], + }, + }, + { + width: 1200, + height: 630, + fonts: [ + { + name: 'Inter', + data: font, + weight: 400, + style: 'normal' as const, + }, + ], + }, + ) + + return new Response(svg, { + headers: { + 'Content-Type': 'image/svg+xml', + 'Cache-Control': 'public, max-age=86400', + }, + }) +} diff --git a/packages/chronicle/src/server/handlers/robots.ts b/packages/chronicle/src/server/handlers/robots.ts new file mode 100644 index 0000000..f5e2eb3 --- /dev/null +++ b/packages/chronicle/src/server/handlers/robots.ts @@ -0,0 +1,11 @@ +import { loadConfig } from '@/lib/config' + +export function handleRobots(): Response { + const config = loadConfig() + const sitemap = config.url ? `\nSitemap: ${config.url}/sitemap.xml` : '' + const body = `User-agent: *\nAllow: /${sitemap}` + + return new Response(body, { + headers: { 'Content-Type': 'text/plain' }, + }) +} diff --git a/packages/chronicle/src/server/handlers/search.ts b/packages/chronicle/src/server/handlers/search.ts new file mode 100644 index 0000000..38ec04b --- /dev/null +++ b/packages/chronicle/src/server/handlers/search.ts @@ -0,0 +1,172 @@ +import fs from 'fs/promises' +import path from 'path' +import matter from 'gray-matter' +import MiniSearch from 'minisearch' +import type { OpenAPIV3 } from 'openapi-types' +import { loadConfig } from '@/lib/config' +import { loadApiSpecs, type ApiSpec } from '@/lib/openapi' +import { getSpecSlug } from '@/lib/api-routes' + +interface SearchDocument { + id: string + url: string + title: string + content: string + type: 'page' | 'api' +} + +let searchIndex: MiniSearch | null = null +let cachedDocs: SearchDocument[] | null = null + +function createIndex(docs: SearchDocument[]): MiniSearch { + const index = new MiniSearch({ + fields: ['title', 'content'], + storeFields: ['url', 'title', 'type'], + searchOptions: { + boost: { title: 2 }, + fuzzy: 0.2, + prefix: true, + }, + }) + index.addAll(docs) + return index +} + +// Try loading pre-built search index (generated at build time) +async function loadPrebuiltIndex(): Promise { + try { + // In bundled server, search-index.json is next to the entry file + const indexPath = path.resolve(__dirname, 'search-index.json') + const raw = await fs.readFile(indexPath, 'utf-8') + return JSON.parse(raw) + } catch { + return null + } +} + +// Fallback: scan filesystem at runtime (dev mode) +function getContentDir(): string { + return process.env.CHRONICLE_CONTENT_DIR || path.join(process.cwd(), 'content') +} + +async function scanContent(): Promise { + const contentDir = getContentDir() + const docs: SearchDocument[] = [] + + async function scan(dir: string, prefix: string[] = []) { + let entries + try { entries = await fs.readdir(dir, { withFileTypes: true }) } + catch { return } + + for (const entry of entries) { + if (entry.name.startsWith('.') || entry.name === 'node_modules') continue + const fullPath = path.join(dir, entry.name) + + if (entry.isDirectory()) { + await scan(fullPath, [...prefix, entry.name]) + continue + } + + if (!entry.name.endsWith('.mdx') && !entry.name.endsWith('.md')) continue + + const raw = await fs.readFile(fullPath, 'utf-8') + const { data: fm, content } = matter(raw) + const baseName = entry.name.replace(/\.(mdx|md)$/, '') + const slugs = baseName === 'index' ? prefix : [...prefix, baseName] + const url = slugs.length === 0 ? '/' : '/' + slugs.join('/') + + docs.push({ + id: url, + url, + title: fm.title ?? baseName, + content: content.slice(0, 5000), + type: 'page', + }) + } + } + + await scan(contentDir) + return docs +} + +function buildApiDocs(): SearchDocument[] { + const config = loadConfig() + if (!config.api?.length) return [] + + const docs: SearchDocument[] = [] + const specs = loadApiSpecs(config.api) + + for (const spec of specs) { + const specSlug = getSpecSlug(spec) + const paths = spec.document.paths ?? {} + for (const [pathStr, pathItem] of Object.entries(paths)) { + if (!pathItem) continue + for (const method of ['get', 'post', 'put', 'delete', 'patch'] as const) { + const op = pathItem[method] as OpenAPIV3.OperationObject | undefined + if (!op?.operationId) continue + const url = `/apis/${specSlug}/${encodeURIComponent(op.operationId)}` + docs.push({ + id: url, + url, + title: `${method.toUpperCase()} ${op.summary ?? op.operationId}`, + content: op.description ?? '', + type: 'api', + }) + } + } + } + + return docs +} + +async function loadDocuments(): Promise { + // Try pre-built index first + const prebuilt = await loadPrebuiltIndex() + if (prebuilt) return prebuilt + + // Fallback to filesystem scanning (dev mode) + const [contentDocs, apiDocs] = await Promise.all([ + scanContent(), + Promise.resolve(buildApiDocs()), + ]) + return [...contentDocs, ...apiDocs] +} + +async function getDocs(): Promise { + if (cachedDocs) return cachedDocs + cachedDocs = await loadDocuments() + return cachedDocs +} + +async function getIndex(): Promise> { + if (searchIndex) return searchIndex + const docs = await getDocs() + searchIndex = createIndex(docs) + return searchIndex +} + +export async function handleSearch(req: Request): Promise { + const url = new URL(req.url) + const query = url.searchParams.get('query') ?? '' + const index = await getIndex() + + if (!query) { + const docs = await getDocs() + const suggestions = docs.filter(d => d.type === 'page').slice(0, 8).map((d) => ({ + id: d.id, + url: d.url, + type: d.type, + content: d.title, + })) + return Response.json(suggestions) + } + + const results = index.search(query).map((r) => ({ + id: r.id, + url: r.url, + type: r.type, + content: r.title, + })) + + return Response.json(results) +} diff --git a/packages/chronicle/src/server/handlers/sitemap.ts b/packages/chronicle/src/server/handlers/sitemap.ts new file mode 100644 index 0000000..6c6b0df --- /dev/null +++ b/packages/chronicle/src/server/handlers/sitemap.ts @@ -0,0 +1,39 @@ +import { loadConfig } from '@/lib/config' +import { getPages } from '@/lib/source' +import { loadApiSpecs } from '@/lib/openapi' +import { buildApiRoutes } from '@/lib/api-routes' + +export async function handleSitemap(): Promise { + const config = loadConfig() + if (!config.url) { + return new Response('', { + headers: { 'Content-Type': 'application/xml' }, + }) + } + + const baseUrl = config.url.replace(/\/$/, '') + + const pages = await getPages() + const docPages = pages.map((page) => { + const lastmod = page.frontmatter.lastModified + ? `${new Date(page.frontmatter.lastModified).toISOString()}` + : '' + return `${baseUrl}/${page.slugs.join('/')}${lastmod}` + }) + + const apiPages = config.api?.length + ? buildApiRoutes(loadApiSpecs(config.api)).map((route) => + `${baseUrl}/apis/${route.slug.join('/')}` + ) + : [] + + const xml = ` + +${baseUrl} +${[...docPages, ...apiPages].join('\n')} +` + + return new Response(xml, { + headers: { 'Content-Type': 'application/xml' }, + }) +} diff --git a/packages/chronicle/src/server/handlers/specs.ts b/packages/chronicle/src/server/handlers/specs.ts new file mode 100644 index 0000000..28b2b23 --- /dev/null +++ b/packages/chronicle/src/server/handlers/specs.ts @@ -0,0 +1,9 @@ +import { loadConfig } from '@/lib/config' +import { loadApiSpecs } from '@/lib/openapi' + +export function handleSpecs(): Response { + const config = loadConfig() + const specs = config.api?.length ? loadApiSpecs(config.api) : [] + + return Response.json(specs) +} diff --git a/packages/chronicle/src/server/index.html b/packages/chronicle/src/server/index.html new file mode 100644 index 0000000..f1a88f8 --- /dev/null +++ b/packages/chronicle/src/server/index.html @@ -0,0 +1,12 @@ + + + + + + + + +
+ + + diff --git a/packages/chronicle/src/server/prod.ts b/packages/chronicle/src/server/prod.ts new file mode 100644 index 0000000..0509df5 --- /dev/null +++ b/packages/chronicle/src/server/prod.ts @@ -0,0 +1,18 @@ +import path from 'path' +import chalk from 'chalk' + +export interface ProdServerOptions { + port: number + root: string + distDir: string +} + +export async function startProdServer(options: ProdServerOptions) { + const { port, distDir } = options + + const serverEntry = path.resolve(distDir, 'server/entry-prod.js') + const { startServer } = await import(serverEntry) + + console.log(chalk.cyan('Starting production server...')) + return startServer({ port, distDir }) +} diff --git a/packages/chronicle/src/server/request-handler.ts b/packages/chronicle/src/server/request-handler.ts new file mode 100644 index 0000000..4f058a2 --- /dev/null +++ b/packages/chronicle/src/server/request-handler.ts @@ -0,0 +1,64 @@ +// Shared request handler for API routes + SSR rendering +// Used by entry-prod.ts (Node) and entry-vercel.ts (Vercel) +import React from 'react' +import { render } from './entry-server' +import { matchRoute } from './router' +import { loadConfig } from '@/lib/config' +import { loadApiSpecs } from '@/lib/openapi' +import { getPage, loadPageComponent, buildPageTree } from '@/lib/source' +import { mdxComponents } from '@/components/mdx' + +export interface RequestHandlerOptions { + template: string + baseUrl: string +} + +export async function handleRequest(url: string, options: RequestHandlerOptions): Promise { + const { template, baseUrl } = options + const fullUrl = new URL(url, baseUrl).href + + // API routes + const routeHandler = matchRoute(fullUrl) + if (routeHandler) { + return routeHandler(new Request(fullUrl)) + } + + // SSR render + const pathname = new URL(url, baseUrl).pathname + const slug = pathname === '/' ? [] : pathname.slice(1).split('/').filter(Boolean) + + const config = loadConfig() + const apiSpecs = config.api?.length ? loadApiSpecs(config.api) : [] + + const [tree, sourcePage] = await Promise.all([ + buildPageTree(), + getPage(slug), + ]) + + let pageData = null + let embeddedData: any = { config, tree, slug, frontmatter: null, filePath: null } + + if (sourcePage) { + const component = await loadPageComponent(sourcePage) + pageData = { + slug, + frontmatter: sourcePage.frontmatter, + content: component ? React.createElement(component, { components: mdxComponents }) : null, + } + embeddedData.frontmatter = sourcePage.frontmatter + embeddedData.filePath = sourcePage.filePath + } + + const html = render(url, { config, tree, page: pageData, apiSpecs }) + + const safeJson = JSON.stringify(embeddedData).replace(/window.__PAGE_DATA__ = ${safeJson}` + const finalHtml = template + .replace('', `${dataScript}`) + .replace('', html) + + return new Response(finalHtml, { + status: 200, + headers: { 'Content-Type': 'text/html' }, + }) +} diff --git a/packages/chronicle/src/server/router.ts b/packages/chronicle/src/server/router.ts new file mode 100644 index 0000000..79b3447 --- /dev/null +++ b/packages/chronicle/src/server/router.ts @@ -0,0 +1,42 @@ +import { handleHealth } from './handlers/health' +import { handleSearch } from './handlers/search' +import { handleApisProxy } from './handlers/apis-proxy' +import { handleOg } from './handlers/og' +import { handleLlms } from './handlers/llms' +import { handleSitemap } from './handlers/sitemap' +import { handleRobots } from './handlers/robots' +import { handleSpecs } from './handlers/specs' + +export type RouteHandler = (req: Request) => Response | Promise + +interface Route { + pattern: URLPattern + handler: RouteHandler +} + +const routes: Route[] = [] + +function addRoute(path: string, handler: RouteHandler) { + routes.push({ + pattern: new URLPattern({ pathname: path }), + handler, + }) +} + +addRoute('/api/health', handleHealth) +addRoute('/api/search', handleSearch) +addRoute('/api/apis-proxy', handleApisProxy) +addRoute('/api/specs', handleSpecs) +addRoute('/og', handleOg) +addRoute('/llms.txt', handleLlms) +addRoute('/sitemap.xml', handleSitemap) +addRoute('/robots.txt', handleRobots) + +export function matchRoute(url: string): RouteHandler | null { + for (const route of routes) { + if (route.pattern.test(url)) { + return route.handler + } + } + return null +} diff --git a/packages/chronicle/src/server/utils/safe-path.ts b/packages/chronicle/src/server/utils/safe-path.ts new file mode 100644 index 0000000..2d3d320 --- /dev/null +++ b/packages/chronicle/src/server/utils/safe-path.ts @@ -0,0 +1,14 @@ +import path from 'path' + +/** + * Resolve a URL path within a base directory, preventing path traversal. + * Returns null if the resolved path escapes the base directory. + */ +export function safePath(baseDir: string, urlPath: string): string | null { + const decoded = decodeURIComponent(urlPath.split('?')[0]) + const resolved = path.resolve(baseDir, '.' + decoded) + if (!resolved.startsWith(path.resolve(baseDir) + path.sep) && resolved !== path.resolve(baseDir)) { + return null + } + return resolved +} diff --git a/packages/chronicle/src/server/vite-config.ts b/packages/chronicle/src/server/vite-config.ts new file mode 100644 index 0000000..ed3adb5 --- /dev/null +++ b/packages/chronicle/src/server/vite-config.ts @@ -0,0 +1,71 @@ +import path from 'path' +import { type InlineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import mdx from '@mdx-js/rollup' +import remarkDirective from 'remark-directive' +import remarkGfm from 'remark-gfm' +import remarkFrontmatter from 'remark-frontmatter' +import remarkMdxFrontmatter from 'remark-mdx-frontmatter' +import rehypeShiki from '@shikijs/rehype' + +export interface ViteConfigOptions { + root: string + contentDir: string + isDev?: boolean +} + +export async function createViteConfig(options: ViteConfigOptions): Promise { + const { root, contentDir, isDev = false } = options + + return { + root, + configFile: false, + resolve: { + alias: { + '@': path.resolve(root, 'src'), + '@content': contentDir, + }, + dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime'], + }, + server: { + fs: { + allow: [root, contentDir], + }, + }, + plugins: [ + mdx({ + remarkPlugins: [ + remarkFrontmatter, + remarkMdxFrontmatter, + remarkGfm, + remarkDirective, + ], + rehypePlugins: [ + [rehypeShiki, { themes: { light: 'github-light', dark: 'github-dark' }, defaultColor: false }], + ], + mdExtensions: ['.md'], + mdxExtensions: ['.mdx'], + }), + react(), + ], + define: { + 'process.env.CHRONICLE_CONTENT_DIR': JSON.stringify(contentDir), + 'process.env.CHRONICLE_PROJECT_ROOT': JSON.stringify(root), + }, + css: { + modules: { + localsConvention: 'camelCase', + }, + }, + ssr: { + noExternal: ['@raystack/apsara'], + }, + build: { + rolldownOptions: { + input: isDev ? undefined : { + client: path.resolve(root, 'src/server/index.html'), + }, + }, + }, + } +} diff --git a/packages/chronicle/src/themes/default/Layout.tsx b/packages/chronicle/src/themes/default/Layout.tsx index 9bb93f6..0e6a65a 100644 --- a/packages/chronicle/src/themes/default/Layout.tsx +++ b/packages/chronicle/src/themes/default/Layout.tsx @@ -1,10 +1,9 @@ "use client"; import { useMemo, useEffect, useRef } from "react"; -import { usePathname } from "next/navigation"; -import NextLink from "next/link"; +import { useLocation, Link } from "react-router-dom"; import { cx } from "class-variance-authority"; -import { Flex, Navbar, Headline, Link, Sidebar, Button } from "@raystack/apsara"; +import { Flex, Navbar, Headline, Sidebar, Button } from "@raystack/apsara"; import { RectangleStackIcon } from "@heroicons/react/24/outline"; import { ClientThemeSwitcher } from "@/components/ui/client-theme-switcher"; import { Search } from "@/components/ui/search"; @@ -25,7 +24,7 @@ const iconMap: Record = { let savedScrollTop = 0; export function Layout({ children, config, tree, classNames }: ThemeLayoutProps) { - const pathname = usePathname(); + const { pathname } = useLocation(); const scrollRef = useRef(null); useEffect(() => { @@ -45,21 +44,21 @@ export function Layout({ children, config, tree, classNames }: ThemeLayoutProps) - + {config.title} - + {config.api?.map((api) => ( - + {api.name} API - + ))} {config.navigation?.links?.map((link) => ( - + {link.label} ))} @@ -118,7 +117,7 @@ function SidebarNode({ const isActive = pathname === item.url; const href = item.url ?? "#"; - const link = useMemo(() => , [href]); + const link = useMemo(() => , [href]); return ( summary::before { + transform: rotate(90deg); +} + +.content details > :not(summary) { + padding: var(--rs-space-4) var(--rs-space-5); +} diff --git a/packages/chronicle/src/themes/default/font.ts b/packages/chronicle/src/themes/default/font.ts index 97d4976..f5110f4 100644 --- a/packages/chronicle/src/themes/default/font.ts +++ b/packages/chronicle/src/themes/default/font.ts @@ -1,6 +1,4 @@ -import { Inter } from 'next/font/google' - -export const inter = Inter({ - subsets: ['latin'], - display: 'swap', -}) +export const inter = { + className: 'chronicle-inter', + style: { fontFamily: "'Inter', system-ui, -apple-system, sans-serif" }, +} diff --git a/packages/chronicle/src/themes/paper/ChapterNav.tsx b/packages/chronicle/src/themes/paper/ChapterNav.tsx index e267d49..b54b54a 100644 --- a/packages/chronicle/src/themes/paper/ChapterNav.tsx +++ b/packages/chronicle/src/themes/paper/ChapterNav.tsx @@ -1,7 +1,6 @@ 'use client' -import { usePathname } from 'next/navigation' -import NextLink from 'next/link' +import { useLocation, Link } from 'react-router-dom' import { MethodBadge } from '@/components/api/method-badge' import type { PageTree, PageTreeItem } from '@/types' import styles from './ChapterNav.module.css' @@ -31,7 +30,7 @@ function buildChapterIndices(children: PageTreeItem[]): Map - {icon && {icon}} {item.name} - + ) } diff --git a/packages/chronicle/src/themes/paper/Page.tsx b/packages/chronicle/src/themes/paper/Page.tsx index 113bcc1..651954c 100644 --- a/packages/chronicle/src/themes/paper/Page.tsx +++ b/packages/chronicle/src/themes/paper/Page.tsx @@ -1,8 +1,7 @@ 'use client' import { useMemo } from 'react' -import { usePathname } from 'next/navigation' -import NextLink from 'next/link' +import { useLocation, Link } from 'react-router-dom' import { Flex } from '@raystack/apsara' import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline' import type { ThemePageProps, PageTreeItem } from '@/types' @@ -41,7 +40,7 @@ function findInTree(items: PageTreeItem[], path: string): PageTreeItem | undefin } export function Page({ page, config, tree }: ThemePageProps) { - const pathname = usePathname() + const { pathname } = useLocation() const { prev, next, crumbs } = useMemo(() => { const pages = flattenTree(tree.children) @@ -59,18 +58,18 @@ export function Page({ page, config, tree }: ThemePageProps) { {prev ? ( - + - + ) : ( )} {next ? ( - + - + ) : (