From a5753efc6a2ca7e13de537198738538d9e906c0b Mon Sep 17 00:00:00 2001 From: Nacho Vazquez Date: Sat, 20 Jun 2026 19:03:52 -0300 Subject: [PATCH] =?UTF-8?q?docs:=20fix=20format=20check=20=E2=80=94=20giti?= =?UTF-8?q?gnore=20TypeDoc=20reference=20+=20.astro,=20remove=20failing=20?= =?UTF-8?q?test=20targets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- .prettierignore | 6 +- CLAUDE.md | 2 +- bun.lock | 463 ++++++++++-------- docs/gonx-docs/astro.config.mjs | 181 ++++++- docs/gonx-docs/project.json | 1 + docs/gonx-docs/src/components/Head.astro | 27 + docs/gonx-docs/src/components/Header.astro | 35 ++ .../gonx-docs/src/components/Pagination.astro | 131 +++++ .../gonx-docs/src/components/PluginLogo.astro | 44 ++ docs/gonx-docs/src/components/Sidebar.astro | 100 ++++ .../src/components/ThemeSelect.astro | 119 +++++ .../content/docs/community/contributing.md | 99 ++++ .../src/content/docs/community/migration.md | 115 +++++ .../src/content/docs/executors/build.md | 58 --- .../src/content/docs/executors/generate.md | 66 --- .../src/content/docs/executors/lint.md | 49 -- .../docs/executors/nx-release-publish.md | 42 -- .../src/content/docs/executors/serve.md | 58 --- .../src/content/docs/executors/test.md | 39 -- .../src/content/docs/executors/tidy.md | 32 -- .../content/docs/generators/application.md | 112 ----- .../content/docs/generators/go-blueprint.md | 206 -------- .../src/content/docs/generators/init.md | 32 -- .../src/content/docs/generators/library.md | 61 --- .../src/content/docs/generators/options.md | 180 ------- .../src/content/docs/generators/preset.md | 167 ------- .../docs/getting-started/installation.md | 90 ++++ .../docs/getting-started/introduction.md | 37 ++ .../docs/getting-started/quick-start.md | 98 ++++ .../content/docs/guides/executors/build.md | 50 ++ .../content/docs/guides/executors/generate.md | 42 ++ .../src/content/docs/guides/executors/lint.md | 39 ++ .../guides/executors/nx-release-publish.md | 57 +++ .../content/docs/guides/executors/serve.md | 40 ++ .../src/content/docs/guides/executors/test.md | 45 ++ .../src/content/docs/guides/executors/tidy.md | 35 ++ .../docs/guides/generators/application.md | 34 ++ .../docs/guides/generators/go-blueprint.md | 40 ++ .../content/docs/guides/generators/init.md | 30 ++ .../content/docs/guides/generators/library.md | 33 ++ .../content/docs/guides/generators/options.md | 57 +++ .../content/docs/guides/generators/preset.md | 45 ++ docs/gonx-docs/src/content/docs/index.mdx | 69 +-- docs/gonx-docs/src/content/docs/migration.md | 199 -------- .../gonx-docs/src/content/docs/quick-start.md | 245 --------- .../src/content/docs/reference/README.md | 10 + .../docs/reference/variables/export=.md | 10 + .../docs/tutorials/first-go-project.md | 139 ++++++ .../docs/understanding/static-analysis.md | 117 +++++ docs/gonx-docs/src/env.d.ts | 16 + docs/gonx-docs/src/lib/code-blocks.ts | 55 +++ docs/gonx-docs/src/lib/copy-for-ai.ts | 61 +++ docs/gonx-docs/src/lib/page-feedback.ts | 45 ++ docs/gonx-docs/src/lib/preferences.ts | 17 + docs/gonx-docs/src/lib/toc-path.ts | 175 +++++++ docs/gonx-docs/src/pages/404.astro | 99 ++-- docs/gonx-docs/src/styles/code-blocks.css | 133 +++++ docs/gonx-docs/src/styles/components.css | 235 +++++++++ docs/gonx-docs/src/styles/custom.css | 245 ++++++--- docs/gonx-docs/src/styles/layout.css | 68 +++ docs/gonx-docs/src/styles/sidebar.css | 139 ++++++ docs/gonx-docs/src/styles/theme-vars.css | 49 ++ docs/gonx-docs/src/styles/toc.css | 67 +++ docs/gonx-docs/tsconfig.json | 13 +- docs/gonx-docs/wrangler.jsonc | 17 +- docs/nx-cloudflare-docs/astro.config.mjs | 196 ++++++++ docs/nx-cloudflare-docs/project.json | 65 +++ docs/nx-cloudflare-docs/public/favicon.svg | 5 + .../src/components/Head.astro | 27 + .../src/components/Header.astro | 43 ++ .../src/components/Pagination.astro | 131 +++++ .../src/components/PluginLogo.astro | 50 ++ .../src/components/Sidebar.astro | 120 +++++ .../src/components/ThemeSelect.astro | 119 +++++ docs/nx-cloudflare-docs/src/content.config.ts | 7 + .../src/content/docs/community/migration.md | 95 ++++ .../docs/getting-started/installation.md | 76 +++ .../docs/getting-started/introduction.md | 27 + .../docs/getting-started/quick-start.md | 121 +++++ .../docs/guides/generators-application.md | 41 ++ .../content/docs/guides/generators-init.md | 45 ++ .../content/docs/guides/generators-library.md | 49 ++ .../src/content/docs/guides/targets-deploy.md | 31 ++ .../src/content/docs/guides/targets-serve.md | 34 ++ .../src/content/docs/guides/targets-tail.md | 32 ++ .../content/docs/guides/targets-typegen.md | 35 ++ .../docs/guides/targets-version-upload.md | 30 ++ .../src/content/docs/index.mdx | 85 ++++ .../src/content/docs/reference/README.md | 30 ++ .../functions/createCloudflareGenerator.md | 24 + .../docs/reference/functions/initGenerator.md | 24 + .../reference/functions/libraryGenerator.md | 24 + .../CreateCloudflareGeneratorSchema.md | 106 ++++ .../interfaces/InitGeneratorSchema.md | 32 ++ .../NxCloudflareLibraryGeneratorSchema.md | 168 +++++++ .../docs/understanding/plugin-options.md | 57 +++ .../content/docs/understanding/wrangler.md | 119 +++++ docs/nx-cloudflare-docs/src/env.d.ts | 16 + .../nx-cloudflare-docs/src/lib/code-blocks.ts | 55 +++ .../nx-cloudflare-docs/src/lib/copy-for-ai.ts | 61 +++ .../src/lib/page-feedback.ts | 45 ++ .../nx-cloudflare-docs/src/lib/preferences.ts | 17 + docs/nx-cloudflare-docs/src/lib/toc-path.ts | 175 +++++++ docs/nx-cloudflare-docs/src/pages/404.astro | 232 +++++++++ .../src/styles/code-blocks.css | 133 +++++ .../src/styles/components.css | 235 +++++++++ docs/nx-cloudflare-docs/src/styles/custom.css | 307 ++++++++++++ docs/nx-cloudflare-docs/src/styles/layout.css | 68 +++ .../nx-cloudflare-docs/src/styles/sidebar.css | 139 ++++++ .../src/styles/theme-vars.css | 49 ++ docs/nx-cloudflare-docs/src/styles/toc.css | 67 +++ docs/nx-cloudflare-docs/tsconfig.json | 14 + docs/nx-cloudflare-docs/wrangler.jsonc | 19 + package.json | 39 +- packages/gonx/README.md | 26 +- .../src/release/go-version-actions.spec.ts | 45 ++ .../gonx/src/release/go-version-actions.ts | 13 +- packages/nx-cloudflare/README.md | 141 +----- 119 files changed, 7292 insertions(+), 2077 deletions(-) create mode 100644 docs/gonx-docs/src/components/Head.astro create mode 100644 docs/gonx-docs/src/components/Header.astro create mode 100644 docs/gonx-docs/src/components/Pagination.astro create mode 100644 docs/gonx-docs/src/components/PluginLogo.astro create mode 100644 docs/gonx-docs/src/components/Sidebar.astro create mode 100644 docs/gonx-docs/src/components/ThemeSelect.astro create mode 100644 docs/gonx-docs/src/content/docs/community/contributing.md create mode 100644 docs/gonx-docs/src/content/docs/community/migration.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/build.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/generate.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/lint.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/nx-release-publish.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/serve.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/test.md delete mode 100644 docs/gonx-docs/src/content/docs/executors/tidy.md delete mode 100644 docs/gonx-docs/src/content/docs/generators/application.md delete mode 100644 docs/gonx-docs/src/content/docs/generators/go-blueprint.md delete mode 100644 docs/gonx-docs/src/content/docs/generators/init.md delete mode 100644 docs/gonx-docs/src/content/docs/generators/library.md delete mode 100644 docs/gonx-docs/src/content/docs/generators/options.md delete mode 100644 docs/gonx-docs/src/content/docs/generators/preset.md create mode 100644 docs/gonx-docs/src/content/docs/getting-started/installation.md create mode 100644 docs/gonx-docs/src/content/docs/getting-started/introduction.md create mode 100644 docs/gonx-docs/src/content/docs/getting-started/quick-start.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/build.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/generate.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/lint.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/nx-release-publish.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/serve.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/test.md create mode 100644 docs/gonx-docs/src/content/docs/guides/executors/tidy.md create mode 100644 docs/gonx-docs/src/content/docs/guides/generators/application.md create mode 100644 docs/gonx-docs/src/content/docs/guides/generators/go-blueprint.md create mode 100644 docs/gonx-docs/src/content/docs/guides/generators/init.md create mode 100644 docs/gonx-docs/src/content/docs/guides/generators/library.md create mode 100644 docs/gonx-docs/src/content/docs/guides/generators/options.md create mode 100644 docs/gonx-docs/src/content/docs/guides/generators/preset.md delete mode 100644 docs/gonx-docs/src/content/docs/migration.md delete mode 100644 docs/gonx-docs/src/content/docs/quick-start.md create mode 100644 docs/gonx-docs/src/content/docs/reference/README.md create mode 100644 docs/gonx-docs/src/content/docs/reference/variables/export=.md create mode 100644 docs/gonx-docs/src/content/docs/tutorials/first-go-project.md create mode 100644 docs/gonx-docs/src/content/docs/understanding/static-analysis.md create mode 100644 docs/gonx-docs/src/env.d.ts create mode 100644 docs/gonx-docs/src/lib/code-blocks.ts create mode 100644 docs/gonx-docs/src/lib/copy-for-ai.ts create mode 100644 docs/gonx-docs/src/lib/page-feedback.ts create mode 100644 docs/gonx-docs/src/lib/preferences.ts create mode 100644 docs/gonx-docs/src/lib/toc-path.ts create mode 100644 docs/gonx-docs/src/styles/code-blocks.css create mode 100644 docs/gonx-docs/src/styles/components.css create mode 100644 docs/gonx-docs/src/styles/layout.css create mode 100644 docs/gonx-docs/src/styles/sidebar.css create mode 100644 docs/gonx-docs/src/styles/theme-vars.css create mode 100644 docs/gonx-docs/src/styles/toc.css create mode 100644 docs/nx-cloudflare-docs/astro.config.mjs create mode 100644 docs/nx-cloudflare-docs/project.json create mode 100644 docs/nx-cloudflare-docs/public/favicon.svg create mode 100644 docs/nx-cloudflare-docs/src/components/Head.astro create mode 100644 docs/nx-cloudflare-docs/src/components/Header.astro create mode 100644 docs/nx-cloudflare-docs/src/components/Pagination.astro create mode 100644 docs/nx-cloudflare-docs/src/components/PluginLogo.astro create mode 100644 docs/nx-cloudflare-docs/src/components/Sidebar.astro create mode 100644 docs/nx-cloudflare-docs/src/components/ThemeSelect.astro create mode 100644 docs/nx-cloudflare-docs/src/content.config.ts create mode 100644 docs/nx-cloudflare-docs/src/content/docs/community/migration.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/getting-started/installation.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/getting-started/introduction.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/getting-started/quick-start.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/generators-application.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/generators-init.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/generators-library.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/targets-deploy.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/targets-serve.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/targets-tail.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/targets-typegen.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/guides/targets-version-upload.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/index.mdx create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/README.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/functions/createCloudflareGenerator.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/functions/initGenerator.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/functions/libraryGenerator.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/CreateCloudflareGeneratorSchema.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/InitGeneratorSchema.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/NxCloudflareLibraryGeneratorSchema.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/understanding/plugin-options.md create mode 100644 docs/nx-cloudflare-docs/src/content/docs/understanding/wrangler.md create mode 100644 docs/nx-cloudflare-docs/src/env.d.ts create mode 100644 docs/nx-cloudflare-docs/src/lib/code-blocks.ts create mode 100644 docs/nx-cloudflare-docs/src/lib/copy-for-ai.ts create mode 100644 docs/nx-cloudflare-docs/src/lib/page-feedback.ts create mode 100644 docs/nx-cloudflare-docs/src/lib/preferences.ts create mode 100644 docs/nx-cloudflare-docs/src/lib/toc-path.ts create mode 100644 docs/nx-cloudflare-docs/src/pages/404.astro create mode 100644 docs/nx-cloudflare-docs/src/styles/code-blocks.css create mode 100644 docs/nx-cloudflare-docs/src/styles/components.css create mode 100644 docs/nx-cloudflare-docs/src/styles/custom.css create mode 100644 docs/nx-cloudflare-docs/src/styles/layout.css create mode 100644 docs/nx-cloudflare-docs/src/styles/sidebar.css create mode 100644 docs/nx-cloudflare-docs/src/styles/theme-vars.css create mode 100644 docs/nx-cloudflare-docs/src/styles/toc.css create mode 100644 docs/nx-cloudflare-docs/tsconfig.json create mode 100644 docs/nx-cloudflare-docs/wrangler.jsonc create mode 100644 packages/gonx/src/release/go-version-actions.spec.ts diff --git a/.gitignore b/.gitignore index 6441dd023..f260add8a 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,7 @@ vitest.config.*.timestamp* .claude/worktrees .nx/polygraph .nx/self-healing -.nx/migrate-runs \ No newline at end of file +.nx/migrate-runs + +# TypeDoc auto-generated API reference +**/src/content/docs/reference/ \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 7ab960c57..8ce97b887 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,4 +14,8 @@ bun.lock .angular /.nx/workspace-data -.nx/self-healing \ No newline at end of file +.nx/self-healing + +# Astro generated + TypeDoc auto-generated reference +.astro +**/src/content/docs/reference/ \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index f525b37f0..0d9aeb822 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,7 +9,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - **`@naxodev/nx-cloudflare`** (`packages/nx-cloudflare`) — Nx plugin for Cloudflare Workers (generators, executors, and a `createNodesV2` inference plugin around Wrangler). - **`@naxodev/gonx`** (`packages/gonx`) — Nx plugin for using Go in an Nx workspace (fork of nx-go, modernized). Includes a tree-sitter–based Go static-analysis graph. -Supporting (non-published) projects: `e2e-utils` (shared e2e helpers), `nx-cloudflare-e2e` / `gonx-e2e` (e2e suites), and `gonx-docs` (Astro Starlight docs site at `packages/docs/gonx-docs`). +Supporting (non-published) projects: `e2e-utils` (shared e2e helpers), `nx-cloudflare-e2e` / `gonx-e2e` (e2e suites), and two Astro Starlight docs sites (`docs/nx-cloudflare-docs`, `docs/gonx-docs`). **Workspace structure:** a **bun workspace** (`workspaces: ["packages/*"]`) using **TypeScript project linking** — a composite `tsconfig.base.json` (`module/moduleResolution: nodenext`, `customConditions: ["@naxodev/source"]`), a root solution `tsconfig.json` with project `references`, and the `@nx/js/typescript` inference plugin (managed by `nx sync`); there are no `tsconfig` `paths`. Shared dependency versions live in a single root `catalog` (referenced as `"catalog:"`); the two plugins' **published** runtime deps stay explicit (loose ranges). Tests run on `bun test` (see below). diff --git a/bun.lock b/bun.lock index dac010cdf..ed6ee0494 100644 --- a/bun.lock +++ b/bun.lock @@ -5,17 +5,29 @@ "": { "name": "@naxodev/oss", "dependencies": { + "@astrojs/react": "catalog:", + "@astrojs/sitemap": "catalog:", "@astrojs/starlight": "catalog:", - "@types/fs-extra": "catalog:", + "@astrojs/starlight-tailwind": "catalog:", + "@tailwindcss/vite": "catalog:", "astro": "catalog:", "hono": "catalog:", "react": "catalog:", "react-dom": "catalog:", "sharp": "catalog:", + "starlight-llms-txt": "catalog:", + "starlight-typedoc": "catalog:", + "tailwindcss": "catalog:", "tslib": "catalog:", + "typedoc": "catalog:", + "typedoc-plugin-markdown": "catalog:", }, "devDependencies": { "@angular-devkit/core": "catalog:", + "@astrojs/react": "catalog:", + "@astrojs/sitemap": "catalog:", + "@astrojs/starlight": "catalog:", + "@astrojs/starlight-tailwind": "catalog:", "@cloudflare/vitest-pool-workers": "catalog:", "@cloudflare/workers-types": "catalog:", "@commitlint/cli": "catalog:", @@ -40,8 +52,10 @@ "@swc/cli": "catalog:", "@swc/core": "catalog:", "@swc/helpers": "catalog:", + "@tailwindcss/vite": "catalog:", "@testing-library/react": "catalog:", "@types/bun": "catalog:", + "@types/fs-extra": "catalog:", "@types/kill-port": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", @@ -73,12 +87,18 @@ "p-limit": "catalog:", "prettier": "catalog:", "semver": "catalog:", + "starlight-llms-txt": "catalog:", + "starlight-typedoc": "catalog:", "strip-indent": "catalog:", + "tailwindcss": "catalog:", "tcp-port-used": "catalog:", "tree-kill": "catalog:", "tree-sitter-go": "catalog:", "ts-node": "catalog:", + "tslib": "catalog:", "tsx": "catalog:", + "typedoc": "catalog:", + "typedoc-plugin-markdown": "catalog:", "typescript": "catalog:", "verdaccio": "catalog:", "vite": "catalog:", @@ -135,7 +155,10 @@ }, "catalog": { "@angular-devkit/core": "~17.3.7", - "@astrojs/starlight": "^0.35.1", + "@astrojs/react": "^5.0.1", + "@astrojs/sitemap": "^3.7.1", + "@astrojs/starlight": "^0.39.0", + "@astrojs/starlight-tailwind": "^5.0.0", "@cloudflare/vitest-pool-workers": "^0.12.0", "@cloudflare/workers-types": "^4.20250404.0", "@commitlint/cli": "^17.8.1", @@ -160,6 +183,7 @@ "@swc/cli": "0.8.1", "@swc/core": "1.15.8", "@swc/helpers": "0.5.23", + "@tailwindcss/vite": "^4.2.2", "@testing-library/react": "16.1.0", "@types/bun": "^1.3.14", "@types/fs-extra": "^11.0.4", @@ -173,7 +197,7 @@ "@typescript-eslint/parser": "7.18.0", "@vitest/coverage-v8": "4.0.9", "@vitest/ui": "4.0.9", - "astro": "^5.6.1", + "astro": "^6.1.0", "chalk": "^4.1.2", "cli-spinners": "^2.9.2", "dotenv": "^16.4.4", @@ -199,16 +223,21 @@ "react-dom": "18.3.1", "semver": "^7.6.0", "sharp": "^0.34.2", + "starlight-llms-txt": "^0.8.0", + "starlight-typedoc": "^0.22.0", "strip-indent": "^3.0.0", + "tailwindcss": "^4.2.2", "tcp-port-used": "^1.0.2", "tree-kill": "^1.2.2", "tree-sitter-go": "^0.25.0", "ts-node": "10.9.1", "tslib": "^2.3.0", "tsx": "^4.19.4", + "typedoc": "^0.28.0", + "typedoc-plugin-markdown": "^4.6.0", "typescript": "5.9.3", "verdaccio": "6.7.2", - "vite": "8.0.9", + "vite": "^7.3.2", "vitest": "4.0.9", "web-tree-sitter": "0.26.3", "wrangler": "^4.26.0", @@ -218,21 +247,25 @@ "@angular-devkit/schematics": ["@angular-devkit/schematics@21.2.14", "", { "dependencies": { "@angular-devkit/core": "21.2.14", "jsonc-parser": "3.3.1", "magic-string": "0.30.21", "ora": "9.3.0", "rxjs": "7.8.2" } }, "sha512-KMJlQSBEzI4+Cy1Zh72gmGQNN2I1vY+nj9CoRcZPBIi1si+0ZAc49XT85eYl+eQumNTVQviUG7LQqgLDAHml+g=="], - "@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], + "@astrojs/compiler": ["@astrojs/compiler@4.0.0", "", {}, "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA=="], + + "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.10.0", "", { "dependencies": { "@types/hast": "^3.0.4", "@types/mdast": "^4.0.4", "js-yaml": "^4.1.1", "picomatch": "^4.0.4", "retext-smartypants": "^6.2.0", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "unified": "^11.0.5" } }, "sha512-Ry2R3VPeIN4uPCSA4xQc+e+vsJXkalKpEbDc07hV+a/o5Bs2N/s/uDcPJH/05L19DKh9tAy7e6JM3YZ6Cxfezw=="], - "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.6", "", {}, "sha512-GOle7smBWKfMSP8osUIGOlB5kaHdQLV3foCsf+5Q9Wsuu+C6Fs3Ez/ttXmhjZ1HkSgsogcM1RXSjjOVieHq16Q=="], + "@astrojs/markdown-remark": ["@astrojs/markdown-remark@7.2.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.10.0", "@astrojs/prism": "4.0.2", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-+YxmVQu1Bd+MFfSzjq1rOJvD9+nIOJzz5YIIhdIH01RrxRkKbyKoEgyIqP3yv51MhzMDgd79QaPv+kCVPT8vHw=="], - "@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.11", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.6", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.21.0", "smol-toml": "^1.6.0", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-hcaxX/5aC6lQgHeGh1i+aauvSwIT6cfyFjKWvExYSxUhZZBBdvCliOtu06gbQyhbe0pGJNoNmqNlQZ5zYUuIyQ=="], + "@astrojs/mdx": ["@astrojs/mdx@5.0.6", "", { "dependencies": { "@astrojs/markdown-remark": "7.1.2", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.16.0", "es-module-lexer": "^2.0.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^6.0.0" } }, "sha512-4dKe0ZMmqujofPNDHahzClkwinn9f8jHPcaXcgdGvPAlboD2mjzkUCofli2cBnxYAkdfhC6d50gBJ8i/cH8gHw=="], - "@astrojs/mdx": ["@astrojs/mdx@4.3.14", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.11", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-FBrqJQORVm+rkRa2TS5CjU9PBA6hkhrwLVBSS9A77gN2+iehvjq1w6yya/d0YKC7osiVorKkr3Qd9wNbl0ZkGA=="], + "@astrojs/prism": ["@astrojs/prism@4.0.2", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA=="], - "@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], + "@astrojs/react": ["@astrojs/react@5.0.7", "", { "dependencies": { "@astrojs/internal-helpers": "0.10.0", "@vitejs/plugin-react": "^5.2.0", "devalue": "^5.8.1", "ultrahtml": "^1.6.0", "vite": "^7.3.2" }, "peerDependencies": { "@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0", "@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0", "react": "^17.0.2 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" } }, "sha512-N9cCoxvnLWaP+AK1Fv4e5Mc7ktnVTpSo2nWLwvD9Ohr1dJKygwrTSm9yatqoahgb1A5Kwjg/rT2shRiIVdn3aw=="], "@astrojs/sitemap": ["@astrojs/sitemap@3.7.3", "", { "dependencies": { "sitemap": "^9.0.0", "stream-replace-string": "^2.0.0", "zod": "^4.3.6" } }, "sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA=="], - "@astrojs/starlight": ["@astrojs/starlight@0.35.3", "", { "dependencies": { "@astrojs/markdown-remark": "^6.3.1", "@astrojs/mdx": "^4.2.3", "@astrojs/sitemap": "^3.3.0", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.41.1", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.1", "hast-util-select": "^6.0.2", "hast-util-to-string": "^3.0.0", "hastscript": "^9.0.0", "i18next": "^23.11.5", "js-yaml": "^4.1.0", "klona": "^2.0.6", "mdast-util-directive": "^3.0.0", "mdast-util-to-markdown": "^2.1.0", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.3.0", "rehype": "^13.0.1", "rehype-format": "^5.0.0", "remark-directive": "^3.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2" }, "peerDependencies": { "astro": "^5.5.0" } }, "sha512-z9MbODjZl/STU3PPU18iOTkLObJBw7PA8xMe5s+KPscQGL0LNZyQUYeClG+F1/em/k+2AsokGpVPta+aOTk1sg=="], + "@astrojs/starlight": ["@astrojs/starlight@0.39.3", "", { "dependencies": { "@astrojs/markdown-remark": "^7.1.1", "@astrojs/mdx": "^5.0.4", "@astrojs/sitemap": "^3.7.2", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.42.0", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.3", "hast-util-select": "^6.0.4", "hast-util-to-string": "^3.0.1", "hastscript": "^9.0.1", "i18next": "^26.0.7", "js-yaml": "^4.1.1", "klona": "^2.0.6", "magic-string": "^0.30.21", "mdast-util-directive": "^3.1.0", "mdast-util-to-markdown": "^2.1.2", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.5.2", "rehype": "^13.0.2", "rehype-format": "^5.0.1", "remark-directive": "^4.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^6.0.0" } }, "sha512-uvAweA2DwhmLgFVfBT9NqG38Ey14k1ck3+y78XNJbceT1pMdzxCCX69RoBajb1QzTJviufsXzSc1xswgRxJfig=="], + + "@astrojs/starlight-tailwind": ["@astrojs/starlight-tailwind@5.0.0", "", { "peerDependencies": { "@astrojs/starlight": ">=0.38.0", "tailwindcss": "^4.0.0" } }, "sha512-VivF+bWg++4ma/ffr5sgHsd/ONtGdVJIKAaRZ6jmL4yqxy7bviu59MGNi5aW3nd8psP9i/aivBTrpwGxRM1XyA=="], - "@astrojs/telemetry": ["@astrojs/telemetry@3.3.0", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ=="], + "@astrojs/telemetry": ["@astrojs/telemetry@3.3.2", "", { "dependencies": { "ci-info": "^4.4.0", "dset": "^3.1.4", "is-docker": "^4.0.0", "is-wsl": "^3.1.1", "which-pm-runs": "^1.1.0" } }, "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ=="], "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], @@ -424,6 +457,10 @@ "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.29.7", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g=="], + "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw=="], + + "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q=="], + "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA=="], "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw=="], @@ -478,6 +515,10 @@ "@capsizecss/unpack": ["@capsizecss/unpack@4.0.0", "", { "dependencies": { "fontkitten": "^1.0.0" } }, "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA=="], + "@clack/core": ["@clack/core@1.4.2", "", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-0Ty/1Gfm+Kb07sXcuESjyKfwEhSy4Ns1AgeEisHb/bDY5fWme0tTeTkU14T1Gmcs17YIjB/teiDe4uaCghbYqQ=="], + + "@clack/prompts": ["@clack/prompts@1.6.0", "", { "dependencies": { "@clack/core": "1.4.2", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-EYlRokl8szrP9Z25qT5aepMdBjzBvHF9ZEhzIiUBc9guz/T31EqRgvD0QSgZcpE93xiwrr+OkB4nz0BZyF6fSA=="], + "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.5.0", "", {}, "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg=="], "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="], @@ -604,13 +645,15 @@ "@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="], - "@expressive-code/core": ["@expressive-code/core@0.41.7", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-ck92uZYZ9Wba2zxkiZLsZGi9N54pMSAVdrI9uW3Oo9AtLglD5RmrdTwbYPCT2S/jC36JGB2i+pnQtBm/Ib2+dg=="], + "@expressive-code/core": ["@expressive-code/core@0.42.0", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-MN11+9nfmaC7sYu2BZJXAXqwkBRt8t1xTSqP+Ti1NfTEskgl6xUnzDxoaiQkg0BMzpglA0pys4dpDKquP/cyIw=="], + + "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.42.0", "", { "dependencies": { "@expressive-code/core": "^0.42.0" } }, "sha512-XtkPm+941Uta7Y+81Acv+OA/20F1NJmJhCX6UYGKpqEIGqplNh3PTOhcURp6tcruhlzJcWcvpWy6Oigz3SrjqA=="], - "@expressive-code/plugin-frames": ["@expressive-code/plugin-frames@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7" } }, "sha512-diKtxjQw/979cTglRFaMCY/sR6hWF0kSMg8jsKLXaZBSfGS0I/Hoe7Qds3vVEgeoW+GHHQzMcwvgx/MOIXhrTA=="], + "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.42.0", "", { "dependencies": { "@expressive-code/core": "^0.42.0", "shiki": "^4.0.2" } }, "sha512-PMKey/kLmewttAHQezL+Y5Fx3vVssfDi3+FJOYQQS2mXP3tQspFELtKKAfsXfmSXdToZYgwoO69HJndqfE+09g=="], - "@expressive-code/plugin-shiki": ["@expressive-code/plugin-shiki@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7", "shiki": "^3.2.2" } }, "sha512-DL605bLrUOgqTdZ0Ot5MlTaWzppRkzzqzeGEu7ODnHF39IkEBbFdsC7pbl3LbUQ1DFtnfx6rD54k/cdofbW6KQ=="], + "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.42.0", "", { "dependencies": { "@expressive-code/core": "^0.42.0" } }, "sha512-l59lUx8fq1v5g6SpmbDjiU0+7IdfbiWnAyRmtTVSpfhyq+nZMN4UcmYyu2b9Mynhzt7Gr+O+cXyEPDNb2AVWVQ=="], - "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7" } }, "sha512-Ewpwuc5t6eFdZmWlFyeuy3e1PTQC0jFvw2Q+2bpcWXbOZhPLsT7+h8lsSIJxb5mS7wZko7cKyQ2RLYDyK6Fpmw=="], + "@gerrit0/mini-shiki": ["@gerrit0/mini-shiki@3.23.0", "", { "dependencies": { "@shikijs/engine-oniguruma": "^3.23.0", "@shikijs/langs": "^3.23.0", "@shikijs/themes": "^3.23.0", "@shikijs/types": "^3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg=="], "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.11.14", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg=="], @@ -892,8 +935,6 @@ "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], - "@oxc-project/types": ["@oxc-project/types@0.126.0", "", {}, "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ=="], - "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.20.0", "", { "os": "android", "cpu": "arm" }, "sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg=="], "@oxc-resolver/binding-android-arm64": ["@oxc-resolver/binding-android-arm64@11.20.0", "", { "os": "android", "cpu": "arm64" }, "sha512-QqslZAuFQG8Q9xm7JuIn8JUbvywhSBMVhuQHtYW+auirZJloS41oxUUaBXk7uUhZJgp44c5zQLeVvmFaDQB+2Q=="], @@ -992,37 +1033,7 @@ "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.16", "", { "os": "android", "cpu": "arm64" }, "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA=="], - - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ=="], - - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ=="], - - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g=="], - - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16", "", { "os": "linux", "cpu": "arm" }, "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg=="], - - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg=="], - - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg=="], - - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.16", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ=="], - - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16", "", { "os": "linux", "cpu": "s390x" }, "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ=="], - - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.16", "", { "os": "linux", "cpu": "x64" }, "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg=="], - - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.16", "", { "os": "linux", "cpu": "x64" }, "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w=="], - - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.16", "", { "os": "none", "cpu": "arm64" }, "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA=="], - - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.16", "", { "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ=="], - - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q=="], - - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.16", "", { "os": "win32", "cpu": "x64" }, "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g=="], - - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.16", "", {}, "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA=="], + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="], "@rollup/plugin-babel": ["@rollup/plugin-babel@6.1.0", "", { "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@rollup/pluginutils": "^5.0.1" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["@types/babel__core", "rollup"] }, "sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA=="], @@ -1120,14 +1131,16 @@ "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], - "@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], + "@shikijs/core": ["@shikijs/core@4.2.0", "", { "dependencies": { "@shikijs/primitive": "4.2.0", "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-Hc87Ab1Ld/vEbZRCbwx344I5v+4RU8CVToUTRkqXL1+TjbuOp9U5Xa0M23V4GEWHxVn+yO5otb+HkQVm3ptWQQ=="], - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.6" } }, "sha512-fjETeq1k5ffyXqRgS6+3hpvqseLalp1kjNfRbXpUgWR8FpZ1CmQfiNHovc5lncYjt/Vg5JK/WJEmLahjwMa0og=="], "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], "@shikijs/langs": ["@shikijs/langs@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg=="], + "@shikijs/primitive": ["@shikijs/primitive@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-NOq+DtUkVBJtZMVXL5A0vI0Xk8nvDYaXetFHSJFlOqjDZIVhIPRYFdGkSoElDqNuegikcc3A76SNUa8dTqtAYA=="], + "@shikijs/themes": ["@shikijs/themes@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0" } }, "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA=="], "@shikijs/types": ["@shikijs/types@3.23.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ=="], @@ -1214,6 +1227,36 @@ "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], + "@tailwindcss/node": ["@tailwindcss/node@4.3.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "5.21.6", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.1" } }, "sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A=="], + + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.1", "@tailwindcss/oxide-darwin-arm64": "4.3.1", "@tailwindcss/oxide-darwin-x64": "4.3.1", "@tailwindcss/oxide-freebsd-x64": "4.3.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.1", "@tailwindcss/oxide-linux-arm64-musl": "4.3.1", "@tailwindcss/oxide-linux-x64-gnu": "4.3.1", "@tailwindcss/oxide-linux-x64-musl": "4.3.1", "@tailwindcss/oxide-wasm32-wasi": "4.3.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.1", "@tailwindcss/oxide-win32-x64-msvc": "4.3.1" } }, "sha512-yVPyo8RNkabVr3O2EhHEE0Rewu7YKzc1DhIqfL46LKveFrmu9XbDazNOJY7/GRuvw1h6u3utWnR29H/p5JPlgA=="], + + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.1", "", { "os": "android", "cpu": "arm64" }, "sha512-SVlyf61g374l5cHyg8x9kf5xmLcOaxvOTsbsqDnSsDJaKOEFZ7GCvi84VAVGpxojYOs1+3K6M0UjXfqPU8vmOQ=="], + + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-hVnWLwv+e/l7c4WKyVtHVrIPvYdqWHjRB3MDIqARynzFtnQg85kmQEFCbV9Ja0VVx4xXTIiDWY60Y7iz/iNoDA=="], + + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Cf7abu0WVgbhU7ANgPUnSAvm7nCvMweusHb8FnaHlLfv/Caq4GYaEZg7ZImzzmjx4lIAfuS8q+eLIS7A7IzxIg=="], + + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-ZZqzX2Y+GXtXXfqSfpJhDm60OoZfvLHLCgm+J7NVqgHHJjG/m9ugZI77RwTsVd4fnBJuCFP6Ae6kTJb71UdS8g=="], + + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.1", "", { "os": "linux", "cpu": "arm" }, "sha512-/Ah/xik0LaMYfv9DZ0S/t4pBlBNYOcqtRwusjgovHkvT8ixueWCLyJjsaF5kQIckjb4IT8Q6K6p/iPmZMixYgg=="], + + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gqdFoVJlw444GvpnheZLHmvTzSxI/cOUUh2KSNejQjTcYkW062SVD+En0rUgD+QV91bz1XGIGtt1HJd48xUGbQ=="], + + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Bwv9KwOvE0VKa86xPFif9b9c3Y1NxOV1P0gLti/IYaWEsQYZXDlxfGEtA8mdDZ7SG3wyNXAWYT5SIn3giL57oA=="], + + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Ymi8O8T15HYQdOUWUtTI6ldN0neHP85FC+Qz32xTcZ7iJXtem/x8ITev0o1e9e5rkqj4lONZfTRLvkmin1+tKg=="], + + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.1", "", { "os": "linux", "cpu": "x64" }, "sha512-M+P/91qJ6uILLw4k2G93GMDRAXj61SMvFQYt39AqvUqYgExXpLL5aepfns7sj4HiAQeolirQF9E0lzRvdf4zPQ=="], + + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.1", "", { "dependencies": { "@emnapi/core": "^1.10.0", "@emnapi/runtime": "^1.10.0", "@emnapi/wasi-threads": "^1.2.1", "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-zsM8uOeqvVGHsAXsJxsT28ttosFahLJKCLOTUBqRAtKnVgGSRitds9T432QiT8b77Yga7JIBkulIRRlJPtYhRA=="], + + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aiNvSq9BsVk8V513lDKlrCFAgf8qBMPZTpgEhInL+NwQqs97mYmupVMrPrgBBSL8Pv/0zXu9MrMF9rMun1ZeNg=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.1", "", { "os": "win32", "cpu": "x64" }, "sha512-xDEyu1rg290472FEGaKHnzyDyh5QH+AlWvsU5hMoMtPpzmKlRI0jaYKCgSHDYtaQWZOYbMaduSyCwFwY4n1HmA=="], + + "@tailwindcss/vite": ["@tailwindcss/vite@4.3.1", "", { "dependencies": { "@tailwindcss/node": "4.3.1", "@tailwindcss/oxide": "4.3.1", "tailwindcss": "4.3.1" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-hItDHuIIlEV61R+faXu66s1K36aTurO/Qw0e45Vskz57gXl9pWOT6eg3zmcEui6CZXddbN7zd41bwmvag4JGwQ=="], + "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], "@testing-library/react": ["@testing-library/react@16.1.0", "", { "dependencies": { "@babel/runtime": "^7.12.5" }, "peerDependencies": { "@testing-library/dom": "^10.0.0", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Q2ToPvg0KsVL0ohND9A3zLJWcOXXcO8IDu3fj11KhNt0UlCWyFyvnCIBkd12tidB2lkiVRG8VFqdhcqhqnAQtg=="], @@ -1244,6 +1287,8 @@ "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], + "@types/braces": ["@types/braces@3.0.5", "", {}, "sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w=="], + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], @@ -1290,6 +1335,8 @@ "@types/mdx": ["@types/mdx@2.0.14", "", {}, "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg=="], + "@types/micromatch": ["@types/micromatch@4.0.10", "", { "dependencies": { "@types/braces": "*" } }, "sha512-5jOhFDElqr4DKTrTEbnW8DZ4Hz5LRUEmyrGpCMrD/NphYv3nUnaF08xmSLx1rGGnyEs/kFnhiw6dCgcDqMr5PQ=="], + "@types/minimist": ["@types/minimist@1.2.5", "", {}, "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag=="], "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], @@ -1430,6 +1477,8 @@ "@verdaccio/utils": ["@verdaccio/utils@8.1.2", "", { "dependencies": { "@verdaccio/core": "8.1.1", "lodash": "4.18.1", "minimatch": "7.4.9" } }, "sha512-LTV6/Kcr8pS//iDjDitfYi1bp0AlKBUuvNoHAbI8tMnj0PLOUtRWJxId5FwuE+z3oNBeDLeOWPoXVtqKjl277Q=="], + "@vitejs/plugin-react": ["@vitejs/plugin-react@5.2.0", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw=="], + "@vitest/coverage-v8": ["@vitest/coverage-v8@4.0.9", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.0.9", "ast-v8-to-istanbul": "^0.3.8", "debug": "^4.4.3", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.2.0", "magicast": "^0.5.1", "std-env": "^3.10.0", "tinyrainbow": "^3.0.3" }, "peerDependencies": { "@vitest/browser": "4.0.9", "vitest": "4.0.9" }, "optionalPeers": ["@vitest/browser"] }, "sha512-70oyhP+Q0HlWBIeGSP74YBw5KSjYhNgSCQjvmuQFciMqnyF36WL2cIkcT7XD85G4JPmBQitEMUsx+XMFv2AzQA=="], "@vitest/expect": ["@vitest/expect@4.0.9", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", "@vitest/spy": "4.0.9", "@vitest/utils": "4.0.9", "chai": "^6.2.0", "tinyrainbow": "^3.0.3" } }, "sha512-C2vyXf5/Jfj1vl4DQYxjib3jzyuswMi/KHHVN2z+H4v16hdJ7jMZ0OGe3uOVIt6LyJsAofDdaJNIFEpQcrSTFw=="], @@ -1532,8 +1581,6 @@ "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], - "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], @@ -1588,9 +1635,9 @@ "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - "astro": ["astro@5.18.2", "", { "dependencies": { "@astrojs/compiler": "^2.13.0", "@astrojs/internal-helpers": "0.7.6", "@astrojs/markdown-remark": "6.3.11", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^4.0.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "acorn": "^8.15.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.3.1", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.1.1", "cssesc": "^3.0.0", "debug": "^4.4.3", "deterministic-object-hash": "^2.0.2", "devalue": "^5.6.2", "diff": "^8.0.3", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.27.3", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.4.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", "magicast": "^0.5.1", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.1", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.3", "shiki": "^3.21.0", "smol-toml": "^1.6.0", "svgo": "^4.0.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tsconfck": "^3.1.6", "ultrahtml": "^1.6.0", "unifont": "~0.7.3", "unist-util-visit": "^5.0.0", "unstorage": "^1.17.4", "vfile": "^6.0.3", "vite": "^6.4.1", "vitefu": "^1.1.1", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.3", "zod": "^3.25.76", "zod-to-json-schema": "^3.25.1", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "astro.js" } }, "sha512-TnFwLnAXty5MXKPDGuKXqK4AMBXG+FH6RUdK7Oyc3gyfNoFIthT+4eRbzOK43bdRlLaZuxgciDSjgtggZ3OtGQ=="], + "astro": ["astro@6.4.8", "", { "dependencies": { "@astrojs/compiler": "^4.0.0", "@astrojs/internal-helpers": "0.10.0", "@astrojs/markdown-remark": "7.2.0", "@astrojs/telemetry": "3.3.2", "@capsizecss/unpack": "^4.0.0", "@clack/prompts": "^1.1.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", "cookie": "^1.1.1", "devalue": "^5.8.1", "diff": "^8.0.3", "dset": "^3.1.4", "es-module-lexer": "^2.0.0", "esbuild": "^0.27.3", "flattie": "^1.1.1", "fontace": "~0.4.1", "get-tsconfig": "5.0.0-beta.4", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "js-yaml": "^4.1.1", "jsonc-parser": "^3.3.1", "magic-string": "^0.30.21", "magicast": "^0.5.2", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "obug": "^2.1.1", "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.4", "rehype": "^13.0.2", "semver": "^7.7.4", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "svgo": "^4.0.1", "tinyclip": "^0.1.12", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "ultrahtml": "^1.6.0", "unifont": "~0.7.4", "unist-util-visit": "^5.1.0", "unstorage": "^1.17.5", "vfile": "^6.0.3", "vite": "^7.3.2", "vitefu": "^1.1.2", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", "zod": "^4.3.6" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "./bin/astro.mjs" } }, "sha512-KK5lX90uU9EeVaTjINyj3sy9/NFXVa59aowaqbWBDDKLXZh4rr7GwIaCFYVetE22MJtsCNFerQXn0vlCLmpP/Q=="], - "astro-expressive-code": ["astro-expressive-code@0.41.7", "", { "dependencies": { "rehype-expressive-code": "^0.41.7" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, "sha512-hUpogGc6DdAd+I7pPXsctyYPRBJDK7Q7d06s4cyP0Vz3OcbziP3FNzN0jZci1BpCvLn9675DvS7B9ctKKX64JQ=="], + "astro-expressive-code": ["astro-expressive-code@0.42.0", "", { "dependencies": { "rehype-expressive-code": "^0.42.0" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, "sha512-aiTePi2Cn0mJPYWZSzP1GcxCinX9mNtJyCCshVVPSg1yRwM7ADvFJOx0FnS440M9t65hp8JH//dc2qr22Bm4ag=="], "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], @@ -1656,8 +1703,6 @@ "bare-url": ["bare-url@2.4.5", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ=="], - "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="], - "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], "baseline-browser-mapping": ["baseline-browser-mapping@2.10.34", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw=="], @@ -1688,8 +1733,6 @@ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], - "brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], @@ -1724,7 +1767,7 @@ "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="], + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], "camelcase-keys": ["camelcase-keys@6.2.2", "", { "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" } }, "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg=="], @@ -1758,8 +1801,6 @@ "cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="], - "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], - "cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], @@ -1798,7 +1839,7 @@ "commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], - "common-ancestor-path": ["common-ancestor-path@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="], + "common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], "common-path-prefix": ["common-path-prefix@3.0.0", "", {}, "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w=="], @@ -1948,8 +1989,6 @@ "detect-port": ["detect-port@2.1.0", "", { "dependencies": { "address": "^2.0.1" }, "bin": { "detect": "dist/commonjs/bin/detect-port.js", "detect-port": "dist/commonjs/bin/detect-port.js" } }, "sha512-epZuWb/6Q62L+nDHJc/hQAqf8pylsqgk3BpZXVBx1CDnr3nkrVNn73Uu1rXcFzkNcc+hkP3whuOg7JZYaQB65Q=="], - "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="], - "devalue": ["devalue@5.8.1", "", {}, "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], @@ -1960,8 +1999,6 @@ "direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="], - "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], - "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], "dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], @@ -2014,7 +2051,7 @@ "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], - "enhanced-resolve": ["enhanced-resolve@5.23.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA=="], + "enhanced-resolve": ["enhanced-resolve@5.21.6", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ=="], "enquirer": ["enquirer@2.3.6", "", { "dependencies": { "ansi-colors": "^4.1.1" } }, "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="], @@ -2128,7 +2165,7 @@ "express-rate-limit": ["express-rate-limit@5.5.1", "", {}, "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg=="], - "expressive-code": ["expressive-code@0.41.7", "", { "dependencies": { "@expressive-code/core": "^0.41.7", "@expressive-code/plugin-frames": "^0.41.7", "@expressive-code/plugin-shiki": "^0.41.7", "@expressive-code/plugin-text-markers": "^0.41.7" } }, "sha512-2wZjC8OQ3TaVEMcBtYY4Va3lo6J+Ai9jf3d4dbhURMJcU4Pbqe6EcHe424MIZI0VHUA1bR6xdpoHYi3yxokWqA=="], + "expressive-code": ["expressive-code@0.42.0", "", { "dependencies": { "@expressive-code/core": "^0.42.0", "@expressive-code/plugin-frames": "^0.42.0", "@expressive-code/plugin-shiki": "^0.42.0", "@expressive-code/plugin-text-markers": "^0.42.0" } }, "sha512-V5DtJLEKuj4wf9O6IRtPtRObkMVy2ggR+S0MdjrTw6m58krZnDioyhW1si3Y04c5YPeooP4nd85Yq9NwEVHS4g=="], "ext-list": ["ext-list@2.2.2", "", { "dependencies": { "mime-db": "^1.28.0" } }, "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA=="], @@ -2148,8 +2185,14 @@ "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], + + "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], + "fast-uri": ["fast-uri@3.1.2", "", {}, "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ=="], + "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="], @@ -2252,6 +2295,8 @@ "get-them-args": ["get-them-args@1.3.2", "", {}, "sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw=="], + "get-tsconfig": ["get-tsconfig@5.0.0-beta.4", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ=="], + "getpass": ["getpass@0.1.7", "", { "dependencies": { "assert-plus": "^1.0.0" } }, "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng=="], "git-raw-commits": ["git-raw-commits@2.0.11", "", { "dependencies": { "dargs": "^7.0.0", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0" }, "bin": { "git-raw-commits": "cli.js" } }, "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A=="], @@ -2338,6 +2383,8 @@ "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], + "hast-util-to-mdast": ["hast-util-to-mdast@10.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-phrasing": "^3.0.0", "hast-util-to-html": "^9.0.0", "hast-util-to-text": "^4.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "mdast-util-to-string": "^4.0.0", "rehype-minify-whitespace": "^6.0.0", "trim-trailing-lines": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ=="], + "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], "hast-util-to-string": ["hast-util-to-string@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A=="], @@ -2386,7 +2433,7 @@ "hyperdyperid": ["hyperdyperid@1.2.0", "", {}, "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A=="], - "i18next": ["i18next@23.16.8", "", { "dependencies": { "@babel/runtime": "^7.23.2" } }, "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg=="], + "i18next": ["i18next@26.3.1", "", { "peerDependencies": { "typescript": "^5 || ^6" }, "optionalPeers": ["typescript"] }, "sha512-txQqd5EULsqEh9OJqRH15aCaOuy/nLJyhw5EHCSKLKJE1aBbb3Zve2+uQIxgWhPm1QqUQoWyQBm2kfmmIrzkcQ=="], "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -2404,8 +2451,6 @@ "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], - "import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="], - "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], @@ -2650,7 +2695,7 @@ "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], - "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], "klona": ["klona@2.0.6", "", {}, "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA=="], @@ -2696,6 +2741,8 @@ "lines-and-columns": ["lines-and-columns@2.0.3", "", {}, "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w=="], + "linkify-it": ["linkify-it@5.0.1", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg=="], + "loader-runner": ["loader-runner@4.3.2", "", {}, "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w=="], "loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="], @@ -2756,6 +2803,8 @@ "lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + "lunr": ["lunr@2.3.9", "", {}, "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="], + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -2774,6 +2823,8 @@ "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], + "markdown-it": ["markdown-it@14.2.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", "linkify-it": "^5.0.1", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ=="], + "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], @@ -2816,6 +2867,8 @@ "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + "mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="], + "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], "memfs": ["memfs@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-fsa": "4.57.6", "@jsonjoy.com/fs-node": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-to-fsa": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/fs-print": "4.57.6", "@jsonjoy.com/fs-snapshot": "4.57.6", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" } }, "sha512-WQK+DGjKCnPdpSyJUXphz+COF2uEhhsxQ3VIWBSbzpbbXuch3h4FePMqXrXGdLjsTgo4JFzBFsP6AWd9pVazGw=="], @@ -2834,7 +2887,7 @@ "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], - "micromark-extension-directive": ["micromark-extension-directive@3.0.2", "", { "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-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA=="], + "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-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=="], @@ -3010,6 +3063,8 @@ "object.values": ["object.values@1.2.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA=="], + "obug": ["obug@2.1.3", "", {}, "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg=="], + "ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "^2.0.5", "node-fetch-native": "^1.6.7", "ufo": "^1.6.1" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], @@ -3048,9 +3103,9 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], - "p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="], + "p-queue": ["p-queue@9.3.0", "", { "dependencies": { "eventemitter3": "^5.0.4", "p-timeout": "^7.0.0" } }, "sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang=="], - "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], + "p-timeout": ["p-timeout@7.0.1", "", {}, "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg=="], "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], @@ -3216,8 +3271,6 @@ "process-warning": ["process-warning@1.0.0", "", {}, "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="], - "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], - "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], @@ -3236,6 +3289,8 @@ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + "pure-rand": ["pure-rand@7.0.1", "", {}, "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ=="], "qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="], @@ -3264,6 +3319,8 @@ "react-is-19": ["react-is@19.2.7", "", {}, "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A=="], + "react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="], + "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], "read-pkg": ["read-pkg@5.2.0", "", { "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", "parse-json": "^5.0.0", "type-fest": "^0.6.0" } }, "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg=="], @@ -3308,19 +3365,23 @@ "rehype": ["rehype@13.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "rehype-parse": "^9.0.0", "rehype-stringify": "^10.0.0", "unified": "^11.0.0" } }, "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A=="], - "rehype-expressive-code": ["rehype-expressive-code@0.41.7", "", { "dependencies": { "expressive-code": "^0.41.7" } }, "sha512-25f8ZMSF1d9CMscX7Cft0TSQIqdwjce2gDOvQ+d/w0FovsMwrSt3ODP4P3Z7wO1jsIJ4eYyaDRnIR/27bd/EMQ=="], + "rehype-expressive-code": ["rehype-expressive-code@0.42.0", "", { "dependencies": { "expressive-code": "^0.42.0" } }, "sha512-8rp/1YMEVVSYbtz+bFBx+uSx3vA4i4T8RwRm5Q/IWbucQnnQqQ0hDqtmKOr8tv+59Cik6cu5aH3WPo0I7csuTA=="], "rehype-format": ["rehype-format@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-format": "^1.0.0" } }, "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ=="], + "rehype-minify-whitespace": ["rehype-minify-whitespace@6.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-minify-whitespace": "^1.0.0" } }, "sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw=="], + "rehype-parse": ["rehype-parse@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-html": "^2.0.0", "unified": "^11.0.0" } }, "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag=="], "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], "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=="], + "rehype-remark": ["rehype-remark@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "hast-util-to-mdast": "^10.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-EmDndlb5NVwXGfUa4c9GPK+lXeItTilLhE6ADSaQuHr4JUlKw9MidzGzx4HpqZrNCt6vnHmEifXQiiA+CEnjYQ=="], + "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="], - "remark-directive": ["remark-directive@3.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", "micromark-extension-directive": "^3.0.0", "unified": "^11.0.0" } }, "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A=="], + "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-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=="], @@ -3348,6 +3409,8 @@ "resolve-global": ["resolve-global@1.0.0", "", { "dependencies": { "global-dirs": "^0.1.1" } }, "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw=="], + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + "resolve.exports": ["resolve.exports@2.0.3", "", {}, "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A=="], "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "^2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], @@ -3366,8 +3429,6 @@ "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], - "rolldown": ["rolldown@1.0.0-rc.16", "", { "dependencies": { "@oxc-project/types": "=0.126.0", "@rolldown/pluginutils": "1.0.0-rc.16" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", "@rolldown/binding-darwin-x64": "1.0.0-rc.16", "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g=="], - "rollup": ["rollup@4.61.1", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.61.1", "@rollup/rollup-android-arm64": "4.61.1", "@rollup/rollup-darwin-arm64": "4.61.1", "@rollup/rollup-darwin-x64": "4.61.1", "@rollup/rollup-freebsd-arm64": "4.61.1", "@rollup/rollup-freebsd-x64": "4.61.1", "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", "@rollup/rollup-linux-arm-musleabihf": "4.61.1", "@rollup/rollup-linux-arm64-gnu": "4.61.1", "@rollup/rollup-linux-arm64-musl": "4.61.1", "@rollup/rollup-linux-loong64-gnu": "4.61.1", "@rollup/rollup-linux-loong64-musl": "4.61.1", "@rollup/rollup-linux-ppc64-gnu": "4.61.1", "@rollup/rollup-linux-ppc64-musl": "4.61.1", "@rollup/rollup-linux-riscv64-gnu": "4.61.1", "@rollup/rollup-linux-riscv64-musl": "4.61.1", "@rollup/rollup-linux-s390x-gnu": "4.61.1", "@rollup/rollup-linux-x64-gnu": "4.61.1", "@rollup/rollup-linux-x64-musl": "4.61.1", "@rollup/rollup-openbsd-x64": "4.61.1", "@rollup/rollup-openharmony-arm64": "4.61.1", "@rollup/rollup-win32-arm64-msvc": "4.61.1", "@rollup/rollup-win32-ia32-msvc": "4.61.1", "@rollup/rollup-win32-x64-gnu": "4.61.1", "@rollup/rollup-win32-x64-msvc": "4.61.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA=="], "rrweb-cssom": ["rrweb-cssom@0.6.0", "", {}, "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw=="], @@ -3474,7 +3535,7 @@ "shell-exec": ["shell-exec@1.1.2", "", {}, "sha512-v2NWVDP0ws+S7miKy2oSpJ/OuL6NKuMosPNUZLDWFBlMnBtuoZxZOwxpQJwhsFZgMb+r7frpDTT8p4OSnhkpsg=="], - "shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], + "shiki": ["shiki@4.2.0", "", { "dependencies": { "@shikijs/core": "4.2.0", "@shikijs/engine-javascript": "4.2.0", "@shikijs/engine-oniguruma": "4.2.0", "@shikijs/langs": "4.2.0", "@shikijs/themes": "4.2.0", "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-hjNax6o/ylDy9lefQEaSDtzaT3iVNtZ3WmpQnbuQNoG4xvnSKf2kSKbihZVO4JRG1TTMejs7CmNRYlWgAL66pQ=="], "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="], @@ -3534,6 +3595,10 @@ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + "starlight-llms-txt": ["starlight-llms-txt@0.8.1", "", { "dependencies": { "@astrojs/mdx": "^5.0.3", "@types/hast": "^3.0.4", "@types/micromatch": "^4.0.10", "github-slugger": "^2.0.0", "hast-util-select": "^6.0.4", "micromatch": "^4.0.8", "rehype-parse": "^9.0.1", "rehype-remark": "^10.0.1", "remark-gfm": "^4.0.1", "remark-stringify": "^11.0.0", "unified": "^11.0.5", "unist-util-remove": "^4.0.0" }, "peerDependencies": { "@astrojs/starlight": ">=0.38.0", "astro": "^6.0.0" } }, "sha512-bRMck9OGNiKXyeJzA6Qy2N/gqC40aERpucOOagl+dPz5s/XeY+9p5dx4wBk3Qiicy3dF/F62Zt9iPPff/POpvA=="], + + "starlight-typedoc": ["starlight-typedoc@0.22.0", "", { "dependencies": { "github-slugger": "^2.0.0" }, "peerDependencies": { "@astrojs/starlight": ">=0.39.0", "typedoc": ">=0.28.0", "typedoc-plugin-markdown": ">=4.6.0" } }, "sha512-Hq2UQh1zKG4Ljs1U9hCdvBwKqFOqt2gUkwOqi6vTtyXW/4JtRkGBNod/+1wTquYBRqxPKUXMcwbACCBqcua4FQ=="], + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], @@ -3616,6 +3681,8 @@ "system-architecture": ["system-architecture@1.0.0", "", {}, "sha512-0OJWD12D7XX3KUg1DYkMaTTjSTo2k/mhIYI3HlBlceXSMcJhW/1qO735fPKS5prcyjvn57Ub151vvASYXpQrEw=="], + "tailwindcss": ["tailwindcss@4.3.1", "", {}, "sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q=="], + "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], @@ -3650,6 +3717,8 @@ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + "tinyclip": ["tinyclip@0.1.14", "", {}, "sha512-F1oWdz8tjT17qe1d5JgDK6z03WGOhYYAN0lK3/D/fzNiy93xswLLEw7pk+3g05onhAy6Bsc6PLNUGhdgVjemMQ=="], + "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], @@ -3686,6 +3755,8 @@ "trim-newlines": ["trim-newlines@3.0.1", "", {}, "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw=="], + "trim-trailing-lines": ["trim-trailing-lines@2.1.0", "", {}, "sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg=="], + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "", { "dependencies": { "utf8-byte-length": "^1.0.1" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="], @@ -3698,8 +3769,6 @@ "ts-node": ["ts-node@10.9.1", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw=="], - "tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="], - "tsconfig-paths": ["tsconfig-paths@4.2.0", "", { "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg=="], "tsconfig-paths-webpack-plugin": ["tsconfig-paths-webpack-plugin@4.2.0", "", { "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", "tapable": "^2.2.1", "tsconfig-paths": "^4.1.2" } }, "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA=="], @@ -3732,8 +3801,14 @@ "typed-assert": ["typed-assert@1.0.9", "", {}, "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg=="], + "typedoc": ["typedoc@0.28.19", "", { "dependencies": { "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", "markdown-it": "^14.1.1", "minimatch": "^10.2.5", "yaml": "^2.8.3" }, "peerDependencies": { "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" }, "bin": { "typedoc": "bin/typedoc" } }, "sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw=="], + + "typedoc-plugin-markdown": ["typedoc-plugin-markdown@4.12.0", "", { "peerDependencies": { "typedoc": "0.28.x" } }, "sha512-eJDEMAfxCmede22c/Jw7d0FA13ggAQv+KkwQYKYCdqI02cin6Rc9QRwbG/7XvvHWinuFejySnZVUWDtvGk3Vbg=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], + "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="], "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], @@ -3780,6 +3855,8 @@ "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": ["unist-util-remove@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg=="], + "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=="], @@ -3842,7 +3919,7 @@ "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.9", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.10", "rolldown": "1.0.0-rc.16", "tinyglobby": "^0.2.16" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.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-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw=="], + "vite": ["vite@7.3.5", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.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", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww=="], "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], @@ -3894,8 +3971,6 @@ "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=="], - "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="], - "wildcard": ["wildcard@2.0.1", "", {}, "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ=="], "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], @@ -3940,19 +4015,13 @@ "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], - "yocto-spinner": ["yocto-spinner@0.2.3", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ=="], - "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], "youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], - "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], - - "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "^4.9.4 || ^5.0.2", "zod": "^3" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="], + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], @@ -3964,11 +4033,15 @@ "@angular-devkit/schematics/rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], - "@astrojs/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "@astrojs/internal-helpers/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + + "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@7.1.2", "", { "dependencies": { "@astrojs/internal-helpers": "0.9.1", "@astrojs/prism": "4.0.2", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "retext-smartypants": "^6.2.0", "shiki": "^4.0.0", "smol-toml": "^1.6.0", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-caXZ4Dc2St2dW8luEg22GlP0gupLdztCTQE4EzZOxW1pqWXz9mbeJEuHUkgDYcKWW8tjIHkydYDhWLVoxJ327Q=="], - "@astrojs/sitemap/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + "@astrojs/mdx/es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], - "@astrojs/telemetry/is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], + "@astrojs/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + + "@astrojs/telemetry/is-docker": ["is-docker@4.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA=="], "@astrojs/telemetry/is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], @@ -4082,18 +4155,10 @@ "@parcel/watcher/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - "@poppinss/colors/kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], - "@poppinss/dumper/@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "@rolldown/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], - - "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], - - "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], - "@rollup/plugin-commonjs/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@rollup/plugin-commonjs/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], @@ -4112,7 +4177,11 @@ "@schematics/angular/jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], - "@svgr/core/camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + "@shikijs/core/@shikijs/types": ["@shikijs/types@4.2.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw=="], + + "@shikijs/engine-javascript/@shikijs/types": ["@shikijs/types@4.2.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw=="], + + "@shikijs/primitive/@shikijs/types": ["@shikijs/types@4.2.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw=="], "@svgr/hast-util-to-babel-ast/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], @@ -4124,6 +4193,20 @@ "@swc/cli/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "@tailwindcss/node/jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" }, "bundled": true }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], + + "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@testing-library/dom/aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], "@types/responselike/@types/node": ["@types/node@24.13.1", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-RSpUJGmvsJ1ZeBehQZFhIdpsz+bIpES0nIQXko4Ybq+N+kX6XvOq3Jo+iJ82FWLdblFq85AsMikd3m35jgezYg=="], @@ -4204,13 +4287,19 @@ "astro/diff": ["diff@8.0.4", "", {}, "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw=="], + "astro/es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], + "astro/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=="], + "astro/jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + + "astro/p-limit": ["p-limit@7.3.0", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw=="], + "astro/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], "astro/tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], - "astro/vite": ["vite@6.4.3", "", { "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-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A=="], + "astro/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "babel-plugin-macros/cosmiconfig": ["cosmiconfig@7.1.0", "", { "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" } }, "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA=="], @@ -4226,14 +4315,6 @@ "body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], - "boxen/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - - "boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - - "boxen/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], - - "boxen/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], - "bun-types/@types/node": ["@types/node@24.13.1", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-RSpUJGmvsJ1ZeBehQZFhIdpsz+bIpES0nIQXko4Ybq+N+kX6XvOq3Jo+iJ82FWLdblFq85AsMikd3m35jgezYg=="], "cacheable-request/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], @@ -4394,8 +4475,6 @@ "jest-util/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - "jest-validate/camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], - "jest-validate/pretty-format": ["pretty-format@30.4.1", "", { "dependencies": { "@jest/schemas": "30.4.1", "ansi-styles": "^5.2.0", "react-is-18": "npm:react-is@^18.3.1", "react-is-19": "npm:react-is@^19.2.5" } }, "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw=="], "jest-watcher/@types/node": ["@types/node@24.13.1", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-RSpUJGmvsJ1ZeBehQZFhIdpsz+bIpES0nIQXko4Ybq+N+kX6XvOq3Jo+iJ82FWLdblFq85AsMikd3m35jgezYg=="], @@ -4412,6 +4491,8 @@ "make-asynchronous/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + "markdown-it/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "meow/type-fest": ["type-fest@0.18.1", "", {}, "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw=="], @@ -4464,6 +4545,8 @@ "object.hasown/es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], + "p-event/p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], + "p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], @@ -4520,6 +4603,14 @@ "set-proto/es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], + "shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-hTorK1dffPkpbMUk6Z+828PgRo7d07HbnizoP0hNPFjhxMHctj0Px/qoHeGMYafc6ju+u9iMldN4JbVzNQM++g=="], + + "shiki/@shikijs/langs": ["@shikijs/langs@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0" } }, "sha512-bwrVRlJ0wUhZxAbVdvBbv2TTC9yLsh4C/IO5Ofz0T8MQntgDvyVnkbjw9vi50r1kx7RCIJdnJnjZAwmAsXFLZQ=="], + + "shiki/@shikijs/themes": ["@shikijs/themes@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0" } }, "sha512-RX8IHYeLv8Cu2W6ruc3RxUqWn0IYCqSrMBzi/uRGAmfyDNOnNO5BF/Px7o97n4XTpmFTo5GbRaazuOWj+2ak2w=="], + + "shiki/@shikijs/types": ["@shikijs/types@4.2.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw=="], + "sitemap/@types/node": ["@types/node@24.13.1", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-RSpUJGmvsJ1ZeBehQZFhIdpsz+bIpES0nIQXko4Ybq+N+kX6XvOq3Jo+iJ82FWLdblFq85AsMikd3m35jgezYg=="], "sitemap/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], @@ -4564,10 +4655,16 @@ "ts-checker-rspack-plugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + "ts-loader/enhanced-resolve": ["enhanced-resolve@5.23.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA=="], + "ts-loader/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "tsconfig-paths-webpack-plugin/enhanced-resolve": ["enhanced-resolve@5.23.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA=="], + "tsx/esbuild": ["esbuild@0.28.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.0", "@esbuild/android-arm": "0.28.0", "@esbuild/android-arm64": "0.28.0", "@esbuild/android-x64": "0.28.0", "@esbuild/darwin-arm64": "0.28.0", "@esbuild/darwin-x64": "0.28.0", "@esbuild/freebsd-arm64": "0.28.0", "@esbuild/freebsd-x64": "0.28.0", "@esbuild/linux-arm": "0.28.0", "@esbuild/linux-arm64": "0.28.0", "@esbuild/linux-ia32": "0.28.0", "@esbuild/linux-loong64": "0.28.0", "@esbuild/linux-mips64el": "0.28.0", "@esbuild/linux-ppc64": "0.28.0", "@esbuild/linux-riscv64": "0.28.0", "@esbuild/linux-s390x": "0.28.0", "@esbuild/linux-x64": "0.28.0", "@esbuild/netbsd-arm64": "0.28.0", "@esbuild/netbsd-x64": "0.28.0", "@esbuild/openbsd-arm64": "0.28.0", "@esbuild/openbsd-x64": "0.28.0", "@esbuild/openharmony-arm64": "0.28.0", "@esbuild/sunos-x64": "0.28.0", "@esbuild/win32-arm64": "0.28.0", "@esbuild/win32-ia32": "0.28.0", "@esbuild/win32-x64": "0.28.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw=="], + "typedoc/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + "unstorage/lru-cache": ["lru-cache@11.5.1", "", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="], "verdaccio/express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="], @@ -4576,18 +4673,20 @@ "verdaccio-audit/express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="], + "vite/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=="], + "vite/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], "vitest/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], "vitest/vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.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", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + "webpack/enhanced-resolve": ["enhanced-resolve@5.23.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA=="], + "webpack/es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], "webpack/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="], - "widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - "wrangler/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=="], "wrangler/miniflare": ["miniflare@4.20260603.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "0.34.5", "undici": "7.24.8", "workerd": "1.20260603.1", "ws": "8.20.1", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-+kMQYB82gC8MPOuojHur3icQsUeZUEJ+Sphuo5rVC3Ri9txBLAW/mH33b9OVrpmkogQeaaqPS4tPtugJZhk5Kw=="], @@ -4616,6 +4715,8 @@ "@angular-devkit/schematics/ora/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.9.1", "", { "dependencies": { "picomatch": "^4.0.4" } }, "sha512-1pWuARqYom/TzuU3+0ZugsTrKlUydWKuULmDqSMTuonY+9IRDUEGKX/8PXQ1nBxRq3w85uGtd9q9SXfqEldMIQ=="], + "@cloudflare/vitest-pool-workers/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], "@cloudflare/vitest-pool-workers/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], @@ -4698,10 +4799,6 @@ "@oxc-resolver/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], - "@rolldown/binding-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], - - "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], - "@rollup/plugin-commonjs/glob/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], "@rspack/binding-wasm32-wasi/@napi-rs/wasm-runtime/@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], @@ -4828,8 +4925,6 @@ "astro/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], - "astro/vite/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=="], - "babel-plugin-macros/cosmiconfig/yaml": ["yaml@1.10.3", "", {}, "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA=="], "binary-version/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], @@ -4848,14 +4943,6 @@ "body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "boxen/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], - - "boxen/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], - - "boxen/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "boxen/wrap-ansi/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], - "bun-types/@types/node/undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], "cacheable-request/get-stream/pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], @@ -5048,13 +5135,55 @@ "verdaccio/express/qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], - "vitest/vite/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=="], + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], - "webpack/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], - "widest-line/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], - "widest-line/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + + "vitest/vite/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=="], + + "webpack/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="], "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], @@ -5110,6 +5239,8 @@ "@angular-devkit/schematics/ora/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + "@cloudflare/vitest-pool-workers/wrangler/workerd/@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260310.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hF2VpoWaMb1fiGCQJqCY6M8I+2QQqjkyY4LiDYdTL5D/w6C1l5v1zhc0/jrjdD1DXfpJtpcSMSmEPjHse4p9Ig=="], "@cloudflare/vitest-pool-workers/wrangler/workerd/@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260310.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-h/Vl3XrYYPI6yFDE27XO1QPq/1G1lKIM8tzZGIWYpntK3IN5XtH3Ee/sLaegpJ49aIJoqhF2mVAZ6Yw+Vk2gJw=="], @@ -5152,66 +5283,10 @@ "@xhmikosr/bin-check/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - "astro/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], - - "astro/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], - - "astro/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], - - "astro/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], - - "astro/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], - - "astro/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], - - "astro/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], - - "astro/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], - - "astro/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], - - "astro/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], - - "astro/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], - - "astro/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], - - "astro/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], - - "astro/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], - - "astro/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], - - "astro/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], - - "astro/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], - - "astro/vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], - - "astro/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], - - "astro/vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], - - "astro/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], - - "astro/vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], - - "astro/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], - - "astro/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], - - "astro/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], - - "astro/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], - "binary-version/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], "binary-version/execa/onetime/mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], - "boxen/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "boxen/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "fork-ts-checker-webpack-plugin/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], @@ -5288,8 +5363,6 @@ "vitest/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], - "widest-line/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "@angular-devkit/schematics/ora/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], "@angular-devkit/schematics/ora/cli-cursor/restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], diff --git a/docs/gonx-docs/astro.config.mjs b/docs/gonx-docs/astro.config.mjs index e34fa64f0..741587de2 100644 --- a/docs/gonx-docs/astro.config.mjs +++ b/docs/gonx-docs/astro.config.mjs @@ -1,11 +1,49 @@ -import { defineConfig } from 'astro/config'; +import react from '@astrojs/react'; +import sitemap from '@astrojs/sitemap'; import starlight from '@astrojs/starlight'; +import tailwindcss from '@tailwindcss/vite'; +import { defineConfig, fontProviders } from 'astro/config'; +import starlightLlmsTxt from 'starlight-llms-txt'; +import { createStarlightTypeDocPlugin } from 'starlight-typedoc'; + +const [gonxTypeDoc, gonxTypeDocSidebarGroup] = createStarlightTypeDocPlugin(); + +const repoRoot = '../../'; +const sourceLinkTemplate = + 'https://github.com/naxodev/oss/blob/main/{path}#L{line}'; export default defineConfig({ + site: 'https://gonx.naxo.dev', + output: 'static', outDir: '../../dist/docs/gonx-docs', + redirects: { + '/': { destination: '/getting-started/introduction/', status: 301 }, + }, + markdown: { + shikiConfig: { + themes: { + light: 'github-light', + dark: 'github-dark', + }, + defaultColor: false, + transformers: [ + { + name: 'meta-title', + pre(node) { + const raw = this.options.meta?.__raw; + if (!raw) return; + const match = raw.match(/title="([^"]+)"/); + if (match) { + node.properties['data-title'] = match[1]; + } + }, + }, + ], + }, + }, integrations: [ starlight({ - title: 'GoNx Docs', + title: 'GoNx', description: 'Nx plugin for Go development', favicon: '/favicon.svg', disable404Route: true, @@ -13,7 +51,7 @@ export default defineConfig({ { icon: 'github', label: 'GitHub', - href: 'https://github.com/naxodev/oss/tree/main/packages/gonx', + href: 'https://github.com/naxodev/oss', }, { icon: 'npm', @@ -26,34 +64,135 @@ export default defineConfig({ href: 'https://discord.gg/zjDCGpKP2S', }, ], + editLink: { + baseUrl: 'https://github.com/naxodev/oss/edit/main/docs/gonx-docs/', + }, + plugins: [ + starlightLlmsTxt({ + projectName: 'GoNx', + description: + 'Nx plugin for Go development — generators, executors, and a tree-sitter–based Go static-analysis graph for Nx workspaces.', + customSets: [ + { + label: 'Getting Started', + paths: ['getting-started/**'], + description: 'Introduction, quick start, and installation', + }, + { + label: 'Guides', + paths: ['guides/**'], + description: 'Task-oriented how-tos for generators and executors', + }, + { + label: 'Reference', + paths: ['reference/**'], + description: 'API documentation for @naxodev/gonx', + }, + ], + promote: ['getting-started/quick-start'], + }), + gonxTypeDoc({ + entryPoints: ['../../packages/gonx/src/index.ts'], + tsconfig: '../../packages/gonx/tsconfig.lib.json', + output: 'reference', + sidebar: { label: '@naxodev/gonx', collapsed: true }, + typeDoc: { + excludeInternal: true, + disableGit: true, + basePath: repoRoot, + sourceLinkTemplate, + }, + }), + ], + customCss: ['./src/styles/custom.css'], + expressiveCode: false, + components: { + Header: './src/components/Header.astro', + Sidebar: './src/components/Sidebar.astro', + ThemeSelect: './src/components/ThemeSelect.astro', + Head: './src/components/Head.astro', + Pagination: './src/components/Pagination.astro', + }, sidebar: [ - { label: 'Quick Start', slug: 'quick-start' }, { - label: 'Generators', + label: 'Getting Started', + items: [ + { slug: 'getting-started/introduction' }, + { slug: 'getting-started/quick-start' }, + { slug: 'getting-started/installation' }, + ], + }, + { + label: 'Tutorials', + items: [{ slug: 'tutorials/first-go-project' }], + }, + { + label: 'Guides', items: [ - { label: 'init', slug: 'generators/init' }, - { label: 'application', slug: 'generators/application' }, - { label: 'library', slug: 'generators/library' }, - { label: 'go-blueprint', slug: 'generators/go-blueprint' }, - { label: 'preset', slug: 'generators/preset' }, - { label: 'options', slug: 'generators/options' }, + { + label: 'Generators', + items: [ + { slug: 'guides/generators/application' }, + { slug: 'guides/generators/library' }, + { slug: 'guides/generators/init' }, + { slug: 'guides/generators/preset' }, + { slug: 'guides/generators/go-blueprint' }, + { slug: 'guides/generators/options' }, + ], + }, + { + label: 'Executors', + items: [ + { slug: 'guides/executors/build' }, + { slug: 'guides/executors/serve' }, + { slug: 'guides/executors/test' }, + { slug: 'guides/executors/lint' }, + { slug: 'guides/executors/tidy' }, + { slug: 'guides/executors/generate' }, + { slug: 'guides/executors/nx-release-publish' }, + ], + }, ], }, { - label: 'Executors', + label: 'Reference', + items: [gonxTypeDocSidebarGroup], + }, + { + label: 'Understanding', + items: [{ slug: 'understanding/static-analysis' }], + }, + { + label: 'Community', items: [ - { label: 'generate', slug: 'executors/generate' }, - { label: 'build', slug: 'executors/build' }, - { label: 'lint', slug: 'executors/lint' }, - { label: 'test', slug: 'executors/test' }, - { label: 'tidy', slug: 'executors/tidy' }, - { label: 'serve', slug: 'executors/serve' }, - { label: 'release', slug: 'executors/nx-release-publish' }, + { slug: 'community/migration' }, + { slug: 'community/contributing' }, ], }, - { label: 'Migration from nx-go', slug: 'migration' }, ], - customCss: ['./src/styles/custom.css'], + lastUpdated: true, + pagination: true, }), + react(), + sitemap(), + ], + vite: { + plugins: [tailwindcss()], + }, + fonts: [ + { + provider: fontProviders.google(), + name: 'Inter', + cssVariable: '--font-heading', + weights: [400, 500, 600, 700], + fallbacks: ['system-ui', 'sans-serif'], + }, + { + provider: fontProviders.google(), + name: 'JetBrains Mono', + cssVariable: '--font-code', + weights: [400, 500], + fallbacks: ['monospace'], + }, ], }); diff --git a/docs/gonx-docs/project.json b/docs/gonx-docs/project.json index f4bf1fd41..cedba1102 100644 --- a/docs/gonx-docs/project.json +++ b/docs/gonx-docs/project.json @@ -7,6 +7,7 @@ "default": ["{projectRoot}/**/*"], "production": ["!{projectRoot}/**/*.spec.tsx"] }, + "implicitDependencies": ["gonx"], "targets": { "build": { "inputs": ["production", "^production"], diff --git a/docs/gonx-docs/src/components/Head.astro b/docs/gonx-docs/src/components/Head.astro new file mode 100644 index 000000000..c143b9119 --- /dev/null +++ b/docs/gonx-docs/src/components/Head.astro @@ -0,0 +1,27 @@ +--- +import { Font } from 'astro:assets'; +import { ClientRouter } from 'astro:transitions'; + +const { head } = Astro.locals.starlightRoute; +--- + +{head.map(({ tag: Tag, attrs, content }) => )} + + + + diff --git a/docs/gonx-docs/src/components/Header.astro b/docs/gonx-docs/src/components/Header.astro new file mode 100644 index 000000000..4512a1d1a --- /dev/null +++ b/docs/gonx-docs/src/components/Header.astro @@ -0,0 +1,35 @@ +--- +import PluginLogo from './PluginLogo.astro'; +--- + +
+ +
+ + diff --git a/docs/gonx-docs/src/components/Pagination.astro b/docs/gonx-docs/src/components/Pagination.astro new file mode 100644 index 000000000..449d7b23b --- /dev/null +++ b/docs/gonx-docs/src/components/Pagination.astro @@ -0,0 +1,131 @@ +--- +const { dir, pagination, id } = Astro.locals.starlightRoute; +const { prev, next } = pagination; +const isRtl = dir === 'rtl'; +--- + +
+ + Was this page helpful? + + + + +
+ + + + + + diff --git a/docs/gonx-docs/src/components/PluginLogo.astro b/docs/gonx-docs/src/components/PluginLogo.astro new file mode 100644 index 000000000..d3739c1ae --- /dev/null +++ b/docs/gonx-docs/src/components/PluginLogo.astro @@ -0,0 +1,44 @@ +--- +interface Props { + height?: number; +} +const { height = 22 } = Astro.props; +--- + + + + diff --git a/docs/gonx-docs/src/components/Sidebar.astro b/docs/gonx-docs/src/components/Sidebar.astro new file mode 100644 index 000000000..f7566dc1b --- /dev/null +++ b/docs/gonx-docs/src/components/Sidebar.astro @@ -0,0 +1,100 @@ +--- +import config from 'virtual:starlight/user-config'; +import Search from 'virtual:starlight/components/Search'; +import SocialIcons from 'virtual:starlight/components/SocialIcons'; +import ThemeSelect from 'virtual:starlight/components/ThemeSelect'; +import SidebarPersister from '@astrojs/starlight/components/SidebarPersister.astro'; +import SidebarSublist from '@astrojs/starlight/components/SidebarSublist.astro'; +import PluginLogo from './PluginLogo.astro'; + +const { sidebar } = Astro.locals.starlightRoute; + +const shouldRenderSearch = + config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro'; +--- + +{/* ── Top chrome (desktop only) ──────────────────────────────────── */} + + +{/* ── Scrollable nav ─────────────────────────────────────────────── */} + + + + +{/* ── Bottom bar (all breakpoints) ────────────────────────────────── */} + + + diff --git a/docs/gonx-docs/src/components/ThemeSelect.astro b/docs/gonx-docs/src/components/ThemeSelect.astro new file mode 100644 index 000000000..67194cb22 --- /dev/null +++ b/docs/gonx-docs/src/components/ThemeSelect.astro @@ -0,0 +1,119 @@ +--- +--- + + + + + +{/* Inlined to avoid FOUC. Uses global scope from ThemeProvider.astro */} + + + + + diff --git a/docs/gonx-docs/src/content/docs/community/contributing.md b/docs/gonx-docs/src/content/docs/community/contributing.md new file mode 100644 index 000000000..2fc0ff5da --- /dev/null +++ b/docs/gonx-docs/src/content/docs/community/contributing.md @@ -0,0 +1,99 @@ +--- +title: Contributing +description: How to contribute to @naxodev/gonx. +--- + +gonx is MIT licensed and developed on +[GitHub](https://github.com/naxodev/oss/tree/main/packages/gonx). Bug reports, +feature requests, and pull requests are all welcome. + +## Development setup + +This repo is a [bun](https://bun.sh/) workspace with Nx. Clone it and install +dependencies: + +```bash +git clone https://github.com/naxodev/oss.git +cd oss +bun install +``` + +You need: + +- **Node.js 22+** +- **bun** (package manager) +- **Go** — a stable release (for running e2e tests) + +## Running tests + +Unit tests run on `bun test`. Run a single spec directly: + +```bash +cd packages/gonx && bun test src/graph/static-analysis/parse-go-mod.spec.ts +``` + +Or run the whole project through Nx (each spec runs in its own bun process for +mock isolation): + +```bash +bunx nx test gonx +``` + +End-to-end tests spin up a local Verdaccio registry and install the published +tarball into a generated workspace: + +```bash +bunx nx e2e gonx-e2e +``` + +## Linting and formatting + +```bash +bunx nx lint gonx +bunx nx format:check +bunx nx format:write +``` + +## Opening a pull request + +1. Create a branch from `main`. +2. Make your changes, keeping commits focused. +3. Run lint, tests, and build before pushing: + + ```bash + bunx nx affected -t lint test build + ``` + +4. Open a PR with a clear description. + +### Commit messages + +Commits are validated by **commitlint** using Conventional Commits. Use the +package scope: + +``` +feat(gonx): add new generator option +fix(gonx): resolve import edge case +docs(gonx): update executor reference +``` + +PR titles matter — squash-merge lands the PR title as the commit subject. Use +`feat(gonx)!: ...` for breaking changes. + +### Coding rules + +- All features or bug fixes must be covered by one or more unit tests. +- All public API methods must be documented. + +## Releasing + +Releases are independent per project and published manually from a maintainer's +machine (the npm account requires 2FA for writes). See +[CONTRIBUTING.md](https://github.com/naxodev/oss/blob/main/CONTRIBUTING.md) for +the full release workflow. + +## Next steps + +- [How static analysis works](/understanding/static-analysis) — understand the tree-sitter graph +- [Plugin options](/guides/generators/options) — the plugin's configuration surface +- [Quick start](/getting-started/quick-start) — get familiar with gonx as a user diff --git a/docs/gonx-docs/src/content/docs/community/migration.md b/docs/gonx-docs/src/content/docs/community/migration.md new file mode 100644 index 000000000..024761aba --- /dev/null +++ b/docs/gonx-docs/src/content/docs/community/migration.md @@ -0,0 +1,115 @@ +--- +title: Migrate to gonx 3.0.0 +description: How to migrate from nx-go or upgrade to @naxodev/gonx 3.0.0. +--- + +import { Steps } from '@astrojs/starlight/components'; + +gonx 3.0.0 requires Nx 23 and infers Go targets from `go.mod` files instead of +generating `project.json` targets. Adapt your workspace with the steps below. + +## Before you start + +- **Nx 23.x** or later +- **Go** — a stable release (1.18+ for multi-module workspaces) +- A backup of your workspace + +## Steps + + +1. **Upgrade to Nx 23** + ```bash + npx nx migrate latest + npx nx migrate --run-migrations + ``` + gonx 3.0.0 requires Nx 23.x. If you are already on 23, skip this step. + +2. **Remove nx-go and install gonx** + If migrating from [@nx-go/nx-go](https://github.com/nx-go/nx-go), uninstall it + first: + + ```bash + npm uninstall @nx-go/nx-go + ``` + + Then install gonx and apply its migrations: + + ```bash + npx nx add @naxodev/gonx + ``` + + If you are upgrading from an earlier gonx release, `nx add` picks up the + migration prompts automatically. + +3. **Register the gonx plugin in `nx.json`** + + ```json + { + "plugins": ["@naxodev/gonx"] + } + ``` + + Remove any nx-go plugin entry. gonx infers targets from `go.mod`, so no + per-project config is needed. + +4. **Delete hand-written Go targets** + gonx infers `build`, `serve`, `test`, `lint`, `tidy`, and `generate` from each + `go.mod`. The main package is auto-detected — a project with `package main` + and `func main()` in `main.go`, or a `cmd/` directory, is treated as an + application and gets `build` and `serve` targets. Remove `project.json` files + that hand-write those targets: + + ```bash + rm apps/my-go-app/project.json + ``` + + Keep `project.json` only for non-Go projects or custom overrides. gonx uses + the full project root path as the project name (for example, + `apps/my-go-app`), not just the final directory segment — this aligns with + Go's release tagging convention (`projectRoot/vx.x.x`). Update any scripts or + CI that reference short project names. + +5. **Remove the `cwd` serve option and review `cmd`/`compiler` values** + The `cwd` serve option no longer exists — serve runs from the project root. + Delete `options.cwd` from any hand-written serve target. Because the main + package is auto-detected, `options.main` is optional. The serve `cmd` and + build `compiler` options now accept `gow` alongside `go` and `tinygo`. See + the [serve executor guide](/guides/executors/serve) and + [build executor guide](/guides/executors/build). + +6. **Decide whether to keep `go.work`** + gonx no longer creates a `go.work` file by default. Build and serve work + without one. Keep an existing `go.work` only if you intentionally use a + multi-module workspace. To opt in when initializing gonx: + + ```bash + npx nx g @naxodev/gonx:init --addGoDotWork + ``` + +7. **Remove `convert-to-one-mod` usage** + The `convert-to-one-mod` generator was removed. Delete any script or doc that + invokes `nx g @naxodev/gonx:convert-to-one-mod`. Consolidate modules manually + with standard Go tooling. + + +## Verify + +Confirm Nx detects your Go projects and infers their targets: + +```bash +npx nx show projects +npx nx show project apps/my-go-app +``` + +`nx show project` lists the inferred targets with no leftover `cwd` options. +Then build a project to confirm it works without `go.work`: + +```bash +npx nx build apps/my-go-app +``` + +## Next steps + +- [Plugin options](/guides/generators/options) — customize target names and tags +- [Create your first Go project](/tutorials/first-go-project) — walkthrough of generators and executors +- [nx-release-publish executor](/guides/executors/nx-release-publish) — publish Go modules diff --git a/docs/gonx-docs/src/content/docs/executors/build.md b/docs/gonx-docs/src/content/docs/executors/build.md deleted file mode 100644 index 4d8c47131..000000000 --- a/docs/gonx-docs/src/content/docs/executors/build.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Build Executor -description: Builds a Go project using the Go compiler ---- - -## Usage - -```bash -nx build my-go-app -``` - -## Options - -| Option | Type | Default | Description | -| ---------- | -------- | ------------------- | --------------------------------------------------------------------------- | -| main | string | - | Relative path from the project root to the main.go file defining the binary | -| compiler | string | "go" | The Go compiler to use (possible values: 'go', 'tinygo') | -| outputPath | string | dist/{project-root} | The output path of the resulting executable | -| buildMode | string | - | Build mode to use | -| env | object | - | Environment variables to set when running the executor | -| flags | string[] | - | Flags to pass to the go compiler | - -## Default Inferred - -```json -{ - "executor": "@naxodev/gonx:build", - "cache": true, - "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"], - "options": { - "outputPath": "dist/{projectRoot}" - }, - "outputs": ["{options.outputPath}"] -} -``` - -## Examples - -### Build with default main.go - -```bash -nx build my-go-app -``` - -### Build with custom main file - -```bash -nx build my-go-app --main=cmd/server/main.go -``` - -This will build the application using the main.go file located at `cmd/server/main.go` relative to the project root. - -## Notes - -- The build executor is cacheable, so subsequent builds with the same inputs will be faster -- Uses the official Go compiler in the background by default but the compiler can be overridden to use `tinygo` or any other Go compiler -- When `main` option is specified, the build command runs from the directory containing the main.go file -- If no `main` option is provided, the build command will discover and build all main packages in the project diff --git a/docs/gonx-docs/src/content/docs/executors/generate.md b/docs/gonx-docs/src/content/docs/executors/generate.md deleted file mode 100644 index a311c1779..000000000 --- a/docs/gonx-docs/src/content/docs/executors/generate.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Generate Executor -description: Runs code generation using the `go generate` command ---- - -## Usage - -```bash -nx run my-go-app:generate -``` - -> **Note**: Use `nx run :generate` instead of `nx generate ` to avoid conflicts with Nx's native generator commands. - -## Options - -| Option | Type | Default | Description | -| ------ | -------- | ------- | ------------------------------------------------------ | -| env | object | - | Environment variables to set when running the executor | -| flags | string[] | - | Flags to pass to the go generate command | - -## Default Inferred - -```json -{ - "executor": "@naxodev/gonx:generate", - "cache": true, - "dependsOn": ["^generate"], - "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] -} -``` - -## Examples - -### Basic code generation - -```bash -nx run my-go-app:generate -``` - -### Generate with verbose output - -```bash -nx run my-go-app:generate --flags=-v -``` - -### Generate with multiple flags - -```bash -nx run my-go-app:generate --flags=-v --flags=-x -``` - -### Generate with custom environment variables - -```bash -nx run my-go-app:generate --env.GOOS=linux --env.GOARCH=amd64 -``` - -## Notes - -- The generate executor is cacheable, so subsequent runs with the same inputs will be faster -- Uses the official `go generate` command in the background -- The generate executor automatically runs before build and test operations due to dependency configuration -- The command searches for `//go:generate` directives in all Go files within the project and its subdirectories -- Generated files should be committed to version control if they are needed for builds -- The executor runs `go generate ./...` to process all packages in the project tree -- **Important**: Always use `nx run :generate` syntax to avoid conflicts with Nx's `nx generate` command for generators diff --git a/docs/gonx-docs/src/content/docs/executors/lint.md b/docs/gonx-docs/src/content/docs/executors/lint.md deleted file mode 100644 index 9a08723b3..000000000 --- a/docs/gonx-docs/src/content/docs/executors/lint.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Lint Executor -description: Formats and lints a Go project ---- - -## Usage - -```bash -nx lint my-go-app -``` - -## Options - -| Option | Type | Default | Description | -| ------ | -------- | -------- | ---------------------------------------- | -| linter | string | "go fmt" | The command to execute instead of go fmt | -| args | string[] | - | Extra args when linting the project | - -## Default Inferred - -```json -{ - "executor": "@naxodev/gonx:lint", - "cache": true, - "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] -} -``` - -### Using golangci-lint - -```json -"@naxodev/gonx:lint": { - "cache": true, - "inputs": [ - "{projectRoot}/go.mod", - "{projectRoot}/go.sum", - "{projectRoot}/**/*.{go}" - ], - "options": { - "linter": "golangci-lint run" - } -}, -``` - -## Notes - -- The lint executor is cacheable -- You can customize the linting tool (for example, use gofmt or golangci-lint instead of go fmt) -- Uses the official Go tooling in the background diff --git a/docs/gonx-docs/src/content/docs/executors/nx-release-publish.md b/docs/gonx-docs/src/content/docs/executors/nx-release-publish.md deleted file mode 100644 index 74e094e28..000000000 --- a/docs/gonx-docs/src/content/docs/executors/nx-release-publish.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Nx-Release-Publish Executor -description: Lists the module in the Golang registry ---- - -## Usage - -```bash -nx nx-release-publish my-go-lib -``` - -or through the `nx release` command: - -```bash -nx release --publish -``` - -## Options - -The nx-release-publish executor does not have configurable options. It automatically publishes your Go module to the Go registry. - -## Default Inferred - -```json -{ - executor: '@naxodev/gonx:release-publish', - options: { - moduleRoot: projectRoot, - }, - configurations: { - development: { - dryRun: true, - }, - }, - } -``` - -## Notes - -- This executor is designed to work seamlessly with `nx release` -- Publishes your Go module to the Go registry -- Part of gonx's integration with Nx's version management system diff --git a/docs/gonx-docs/src/content/docs/executors/serve.md b/docs/gonx-docs/src/content/docs/executors/serve.md deleted file mode 100644 index 7f19700ca..000000000 --- a/docs/gonx-docs/src/content/docs/executors/serve.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Serve Executor -description: Runs a Go application ---- - -## Usage - -```bash -nx serve my-go-app -``` - -## Options - -| Option | Type | Default | Description | -| ------ | -------- | ------- | --------------------------------------------------------------------------- | -| main | string | - | Relative path from the project root to the main.go file defining the binary | -| cmd | string | "go" | Name of the go binary to use | -| args | string[] | - | Extra args when starting the app | -| env | object | - | Environment variables to set when running the application | - -## Default Inferred - -```json -{ - "executor": "@naxodev/gonx:serve", - "continuous": true, - "options": {} -} -``` - -## Examples - -### Serve with default main.go - -```bash -nx serve my-go-app -``` - -### Serve with custom main file - -```bash -nx serve my-go-app --main=cmd/server/main.go -``` - -This will run the application using the main.go file located at `cmd/server/main.go` relative to the project root. - -### Serve with arguments - -```bash -nx serve my-go-app --args="--port=8080,--debug" -``` - -## Notes - -- Automatically discovers `main.go` files when no explicit main file is specified -- Uses the official `go run` commands in the background, but it can be overridden to use any other command -- When `main` option is specified, the serve command runs from the directory containing the main.go file -- If no `main` option is provided, the serve command will discover and run the main package in the project root diff --git a/docs/gonx-docs/src/content/docs/executors/test.md b/docs/gonx-docs/src/content/docs/executors/test.md deleted file mode 100644 index d362db42a..000000000 --- a/docs/gonx-docs/src/content/docs/executors/test.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Test Executor -description: Runs tests for a Go project ---- - -## Usage - -```bash -nx test my-go-app -``` - -## Options - -| Option | Type | Default | Description | -| ------------ | ------- | ------- | ---------------------------------------------------------------- | -| cover | boolean | false | Enable coverage analysis | -| coverProfile | string | - | Write a coverage profile to the file after all tests have passed | -| race | boolean | false | Enable race detector | -| run | string | - | Run only tests matching this regular expression | -| verbose | boolean | false | Enable verbose test output | -| count | number | - | Run test N times | -| timeout | string | "10m" | Test timeout duration (0 to disable) | - -## Default Inferred - -```json -{ - "executor": "@naxodev/gonx:test", - "cache": true, - "dependsOn": ["^build"], - "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] -} -``` - -## Notes - -- The test executor is cacheable, so subsequent test runs with the same test code will be faster -- Uses the official Go test command in the background -- Supports all common Go test options diff --git a/docs/gonx-docs/src/content/docs/executors/tidy.md b/docs/gonx-docs/src/content/docs/executors/tidy.md deleted file mode 100644 index 0ae2a32a1..000000000 --- a/docs/gonx-docs/src/content/docs/executors/tidy.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Tidy Executor -description: Ensures go.mod file matches the project's source code ---- - -## Usage - -```bash -nx tidy my-go-app -``` - -## Options - -| Option | Type | Default | Description | -| ------- | ------- | ------- | --------------------- | -| verbose | boolean | false | Enable verbose output | - -## Default Inferred - -```json -{ - "executor": "@naxodev/gonx:tidy", - "cache": true, - "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] -} -``` - -## Notes - -- The tidy executor is cacheable -- Uses the official Go mod tidy command in the background -- Ensures that the go.mod file accurately reflects your project dependencies diff --git a/docs/gonx-docs/src/content/docs/generators/application.md b/docs/gonx-docs/src/content/docs/generators/application.md deleted file mode 100644 index 0df0c3bc3..000000000 --- a/docs/gonx-docs/src/content/docs/generators/application.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: Application Generator -description: Generates a Go application with a well-structured foundation ---- - -## Usage - -```bash -nx g @naxodev/gonx:application my-go-app -``` - -## Options - -| Option | Type | Default | Description | -| ---------- | ---------------------------- | ---------- | ---------------------------------------------- | -| name | string | null | Name of the Go application | -| directory | string | \*required | The directory of the new application | -| template | `standard` \| `cli` \| `tui` | `standard` | The template of application to generate | -| tags | string | null | Add tags to the application (used for linting) | -| skipFormat | boolean | false | Skip formatting files | - -## Examples - -### Generate a standard application (default) - -```bash -nx g @naxodev/gonx:application my-go-app -``` - -### Generate a CLI application - -```bash -nx g @naxodev/gonx:application my-cli-app --template=cli -``` - -### Generate a TUI application - -```bash -nx g @naxodev/gonx:application my-tui-app --template=tui -``` - -### Generate an application in a specific directory - -```bash -nx g @naxodev/gonx:application apps/my-go-app -``` - -or - -```bash -nx g @naxodev/gonx:application --name=go-app --directory=apps/my-go-app -``` - -### Generate an application with tags - -> [!NOTE] -> Tags will only work when the project was created with a project.json file - -```bash -nx g @naxodev/gonx:application my-go-app --tags="json yaml" -``` - -## Output - -The generator creates different structures based on the application template: - -### Standard Application (default) - -``` -my-go-app/ -├── main.go -├── main_test.go -└── go.mod -``` - -### CLI Application (--template=cli) - -``` -my-cli-app/ -├── main.go -├── main_test.go -├── go.mod -└── cmd/ - ├── root.go - ├── version.go - └── cmd_test.go -``` - -### TUI Application (--template=tui) - -``` -my-tui-app/ -├── main.go -├── main_test.go -├── go.mod -├── cmd/ - └── root.go -└── internal/ - └── models/ - ├── model.go - ├── model_test.go - └── styles/ - ├── styles.go -``` - -## Notes - -- Unlike the original nx-go, gonx does not generate a project.json file -- Uses inferred tasks, so you can immediately use `nx build`, `nx serve`, etc. -- **CLI applications** use [Cobra](https://github.com/spf13/cobra) for professional command-line interfaces -- **TUI applications** use [Bubble Tea](https://github.com/charmbracelet/bubbletea) and [Lipgloss](https://github.com/charmbracelet/lipgloss) for interactive terminal UIs -- For CLI and TUI apps, run `nx tidy ` after generation to download dependencies diff --git a/docs/gonx-docs/src/content/docs/generators/go-blueprint.md b/docs/gonx-docs/src/content/docs/generators/go-blueprint.md deleted file mode 100644 index 74ee2a236..000000000 --- a/docs/gonx-docs/src/content/docs/generators/go-blueprint.md +++ /dev/null @@ -1,206 +0,0 @@ ---- -title: Go Blueprint Generator -description: Uses [Go Blueprint](https://github.com/Melkeydev/go-blueprint) to generate Go applications with various frameworks and features. This generator integrates Go Blueprint's powerful scaffolding capabilities with Nx's workflow ---- - -The Go Blueprint binary is included with this package, so no additional installation is required. - -## Usage - -```bash -nx g @naxodev/gonx:go-blueprint my-go-app -``` - -The generator will prompt you to select: - -- Web framework -- Database driver -- Git handling preference -- Advanced features (optional) - -## Options - -| Option | Type | Default | Description | -| ------------ | ------- | ---------- | ------------------------------------------ | -| directory | string | \*required | The directory of the new application | -| name | string | null | The name of the application | -| tags | string | null | Add tags to the project (used for linting) | -| skipFormat | boolean | false | Skip formatting files | -| addGoDotWork | boolean | false | Add this project to go.work file | -| framework | string | \*required | Web framework to use | -| driver | string | \*required | Database driver to use | -| git | string | \*required | Git handling preference | -| feature | array | [] | Advanced features to include | - -### Framework Options - -- `chi` - Chi router -- `gin` - Gin web framework -- `fiber` - Fiber web framework -- `gorilla/mux` - Gorilla Mux router -- `httprouter` - HttpRouter -- `standard-library` - Go standard library -- `echo` - Echo web framework - -### Database Driver Options - -- `mysql` - MySQL database -- `postgres` - PostgreSQL database -- `sqlite` - SQLite database -- `mongo` - MongoDB -- `redis` - Redis -- `scylla` - ScyllaDB -- `none` - No database - -### Git Options - -- `commit` - Initialize git and commit changes -- `stage` - Initialize git and stage changes -- `skip` - Skip git initialization - -### Advanced Features - -- `react` - React frontend integration (⚠️ **Not recommended** - see Frontend Integration below) -- `htmx` - HTMX integration -- `githubaction` - GitHub Actions workflow -- `websocket` - WebSocket support -- `tailwind` - Tailwind CSS -- `docker` - Docker configuration - -## Examples - -### Basic Usage with Prompts - -```bash -nx g @naxodev/gonx:go-blueprint my-api -``` - -This will prompt you to select all required options interactively. - -### Specify All Options - -```bash -nx g @naxodev/gonx:go-blueprint my-api \ - --framework=gin \ - --driver=postgres \ - --git=commit \ - --feature=docker,githubaction -``` - -### Generate in Specific Directory - -```bash -nx g @naxodev/gonx:go-blueprint apps/my-api \ - --framework=fiber \ - --driver=mysql \ - --git=stage -``` - -### Add to Go Workspace - -```bash -nx g @naxodev/gonx:go-blueprint my-service \ - --framework=chi \ - --driver=none \ - --git=skip \ - --addGoDotWork=true -``` - -## Output - -The generator creates a fully-featured Go application based on your selections. The exact structure depends on the chosen framework and features, but typically includes: - -``` -my-go-app/ -├── main.go -├── go.mod -├── go.sum -├── handlers/ -├── models/ -├── database/ -├── static/ -└── ... (additional files based on selected features) -``` - -## Integration with Nx - -After generation, you can use all standard Nx commands: - -```bash -# Build the application -nx build my-go-app - -# Run the application -nx serve my-go-app - -# Run tests -nx test my-go-app - -# Lint the code -nx lint my-go-app - -# Manage dependencies -nx tidy my-go-app -``` - -## Frontend Integration - -:::caution -Avoid using Go Blueprint's built-in frontend features (like `react`) as they will not be properly detected by Nx's project graph. Since Nx already detects a Go project in the directory, adding frontend code directly will create conflicts. -::: - -### Recommended Approach - -Instead of using Go Blueprint's frontend features, create separate frontend projects using Nx's native generators: - -```bash -# Generate your Go API first -nx g @naxodev/gonx:go-blueprint my-api --framework=gin --driver=postgres --git=skip - -# Then generate a separate frontend project -nx g @nx/react:app frontend --directory=apps/frontend - -# Or use other Nx frontend generators -nx g @nx/angular:app frontend --directory=apps/frontend -nx g @nx/vue:app frontend --directory=apps/frontend -``` - -### Benefits of Separate Projects - -- ✅ Proper Nx project graph detection and dependency tracking -- ✅ Independent build, test, and deployment pipelines -- ✅ Better separation of concerns -- ✅ Full access to Nx's frontend tooling and optimizations -- ✅ Easier to scale and maintain - -### Example Workspace Structure - -``` -my-workspace/ -├── apps/ -│ ├── my-api/ # Go API (generated with go-blueprint) -│ │ ├── main.go -│ │ └── go.mod -│ └── frontend/ # React/Angular/Vue app (generated with Nx) -│ ├── src/ -│ └── package.json -└── nx.json -``` - -## Notes - -- Go Blueprint binary is bundled with this package -- Uses Nx's inferred tasks, so no project.json file is generated -- Follows gonx's philosophy of keeping non-JS monorepos pure -- All Go Blueprint options are mapped to provide a seamless integration experience - -## Troubleshooting - -### Generation Fails - -If generation fails: - -1. Check that the target directory doesn't already exist -2. Ensure you have write permissions to the target location -3. Verify all required options are provided -4. Check [Go Blueprint documentation](https://docs.go-blueprint.dev/) for framework-specific requirements diff --git a/docs/gonx-docs/src/content/docs/generators/init.md b/docs/gonx-docs/src/content/docs/generators/init.md deleted file mode 100644 index 8c870cadb..000000000 --- a/docs/gonx-docs/src/content/docs/generators/init.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Init Generator -description: Initializes gonx in an existing Nx workspace ---- - -:::caution -This is an internal generator, not intended to be use directly as Nx does. -::: - -## Usage - -```bash -nx g @naxodev/gonx:init -``` - -## Options - -This generator does not have configurable options. - -## Example - -```bash -nx g @naxodev/gonx:init -``` - -## Notes - -- Sets up the workspace for Go development -- Configures the workspace for Go development -- Can be used with `nx add @naxodev/gonx` to add gonx to an existing workspace -- Creates the necessary configuration files for Go development -- Creates go.work file only when explicitly requested via the `addGoDotWork` option diff --git a/docs/gonx-docs/src/content/docs/generators/library.md b/docs/gonx-docs/src/content/docs/generators/library.md deleted file mode 100644 index ec7b9106e..000000000 --- a/docs/gonx-docs/src/content/docs/generators/library.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: Library Generator -description: Generates a Go library with a well-structured foundation ---- - -## Usage - -```bash -nx g @naxodev/gonx:library my-go-lib -``` - -## Options - -| Option | Type | Default | Description | -| ---------- | ------- | ---------- | ------------------------------------------ | -| name | string | null | Name of the Go library | -| directory | string | \*required | The directory of the new library | -| tags | string | null | Add tags to the library (used for linting) | -| skipFormat | boolean | false | Skip formatting files | - -## Examples - -### Generate a library in the root - -```bash -nx g @naxodev/gonx:library my-go-lib -``` - -### Generate a library in a specific directory - -```bash -nx g @naxodev/gonx:library libs/my-go-lib -``` - -### Generate a library with tags - -> [!NOTE] -> Tags will only work when the project was created with a project.json file - -```bash -nx g @naxodev/gonx:library my-go-lib --tags="json yaml" -``` - -## Output - -The generator creates a Go library with the following structure: - -``` -my-go-lib/ -├── go.mod -├── go.sum -├── my-go-lib.go -└── my-go-lib.go_test.go -``` - -## Notes - -- Unlike the original nx-go, gonx does not generate a project.json file -- Uses inferred tasks, so you can immediately use `nx build`, `nx test`, etc. -- Works with both single and multi-module Go workspace configurations -- Integrated with Nx release system for version management diff --git a/docs/gonx-docs/src/content/docs/generators/options.md b/docs/gonx-docs/src/content/docs/generators/options.md deleted file mode 100644 index 751f558c0..000000000 --- a/docs/gonx-docs/src/content/docs/generators/options.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: Configuration Options -description: gonx provides several configuration options to customize your Go development experience within Nx ---- - -## Workspace Configuration - -By default, gonx sets up projects without creating a go.work file, keeping the workspace lightweight. You can enable multi-module Go workspace configuration by using the `addGoDotWork` option when setting up your workspace, which provides better integration with Nx's dependency graph and caching features for complex Go projects. - -## Inferred Tasks - -gonx leverages Nx's inferred tasks feature, which means you don't need to have project.json files for your Go projects. The following tasks are automatically available: - -| Task | Command | Description | -| -------- | ----------------------- | ----------------------------------------- | -| build | `nx build ` | Builds the Go application | -| generate | `nx run :generate` | Runs code generation using go generate | -| serve | `nx serve ` | Runs the Go application | -| test | `nx test ` | Runs tests for the Go project | -| lint | `nx lint ` | Formats and lints the Go project | -| tidy | `nx tidy ` | Ensures go.mod matches the project source | -| publish | (with nx release) | Publishes the Go module to the registry | - -## Nx Release Integration - -gonx integrates with Nx's release system, providing: - -1. Version management for Go modules -2. Publishing to the Go registry -3. Semantic versioning support - -To use this feature, you can run: - -```bash -nx release -``` - -This will handle versioning and publishing your Go modules. - -## Custom Task Configuration - -If you want to override the default inferred task configuration, you can create a project.json file in your Go project directory with custom executor options. This gives you fine-grained control while still benefiting from gonx's integration with Nx. - -Example project.json: - -```json -{ - "name": "my-go-app", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "targets": { - "build": { - "executor": "@naxodev/gonx:build", - "options": { - "main": "my-go-app/cmd/my-go-app/main.go", - "outputPath": "dist/apps/my-go-app", - "env": { - "GOOS": "linux", - "GOARCH": "amd64" - } - } - } - } -} -``` - -Or if you want to stay project-less you can configure it in the `nx.json` - -```json -{ - ... - "targetDefaults": { - ... - "@naxodev/gonx:lint": { - "cache": true, - "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"], - "options": { - "linter": "golangci-lint run" - } - } - } -} -``` - -## Environment Variables - -You can configure environment variables for Go commands using the `env` option in the executor configuration: - -```json -{ - "build": { - "executor": "@naxodev/gonx:build", - "options": { - "main": "my-go-app/cmd/my-go-app/main.go", - "env": { - "GOOS": "linux", - "GOARCH": "amd64" - } - } - } -} -``` - -## Compiler Options - -For the build executor, you can choose between the standard Go compiler and TinyGo using the `compiler` option: - -```json -{ - "build": { - "executor": "@naxodev/gonx:build", - "options": { - "main": "my-go-app/cmd/my-go-app/main.go", - "compiler": "tinygo" - } - } -} -``` - -## Custom Linting - -You can configure custom linting tools instead of the default `go fmt`: - -```json -{ - "lint": { - "executor": "@naxodev/gonx:lint", - "options": { - "linter": "golangci-lint", - "args": ["run"] - } - } -} -``` - -## Code Generation - -You can configure the generate executor with custom flags and environment variables: - -```json -{ - "generate": { - "executor": "@naxodev/gonx:generate", - "options": { - "flags": ["-v"], - "env": { - "GOOS": "linux", - "GOARCH": "amd64" - } - } - } -} -``` - -# Plugin Options - -The plugin allows to configure its behavior with global options. - -## Usage - -Import the plugin with an object instead of a simple string in your `nx.json` file. - -Here is an example: - -```json -{ - "$schema": "./node_modules/nx/schemas/nx-schema.json", - "plugins": [ - { - "plugin": "@naxodev/gonx", - "options": { "skipGoDependencyCheck": true } - } - ] -} -``` - -## Options - -### skipGoDependencyCheck - -- (boolean): if true, the plugin will not require to have Go installed to compute a Nx workspace graph. Be aware that if Go is not installed, the plugin will not be able to detect dependencies between Go projects and this is source of misunderstanding. diff --git a/docs/gonx-docs/src/content/docs/generators/preset.md b/docs/gonx-docs/src/content/docs/generators/preset.md deleted file mode 100644 index 0eb433b5e..000000000 --- a/docs/gonx-docs/src/content/docs/generators/preset.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -title: Preset Generator -description: Preset generator for creating a new workspace with gonx pre-configured. Choose between different project types to bootstrap your Go development ---- - -## Usage - -```bash -npx create-nx-workspace go-workspace --preset=@naxodev/gonx -``` - -When you run this command, you'll be prompted to select a template type: - -- **Binary** - Creates a Go application using the standard gonx generator -- **Library** - Creates a Go library using the gonx library generator -- **Go Blueprint** - Creates a Go application using Go Blueprint templates - -## Options - -| Option | Type | Default | Description | -| ------------ | ------- | ---------- | -------------------------------------------------- | -| type | string | "binary" | Template type: "binary", "library", "go-blueprint" | -| directory | string | \*required | The directory of the new project | -| name | string | null | The name of the project | -| tags | string | null | Add tags to the project (used for linting) | -| skipFormat | boolean | false | Skip formatting files | -| addGoDotWork | boolean | false | Add this project to go.work file | - -### Go Blueprint Specific Options - -When `type` is set to "go-blueprint", additional options become available: - -| Option | Type | Default | Description | -| --------- | ------ | ------- | -------------------------------------------------------------------------------- | -| framework | string | "gin" | Web framework (chi, gin, fiber, gorilla/mux, httprouter, standard-library, echo) | -| driver | string | "none" | Database driver (mysql, postgres, sqlite, mongo, redis, scylla, none) | -| git | string | "skip" | Git handling (commit, stage, skip) | -| feature | array | [] | Advanced features (react, htmx, githubaction, websocket, tailwind, docker) | - -## Examples - -### Interactive Mode (Recommended) - -```bash -npx create-nx-workspace my-go-workspace --preset=@naxodev/gonx -``` - -This will prompt you to select the template type and configure all options interactively. - -### Create Binary Application - -```bash -npx create-nx-workspace go-app --preset=@naxodev/gonx --type=binary -``` - -### Create Library - -```bash -npx create-nx-workspace go-lib --preset=@naxodev/gonx --type=library -``` - -### Create Go Blueprint Application - -```bash -npx create-nx-workspace go-api --preset=@naxodev/gonx --type=go-blueprint --framework=gin --driver=postgres --git=commit -``` - -### Go Blueprint with Advanced Features - -```bash -npx create-nx-workspace go-app --preset=@naxodev/gonx \ - --type=go-blueprint \ - --framework=fiber \ - --driver=mysql \ - --git=stage \ - --feature=docker,githubaction -``` - -### With Go Workspace - -```bash -npx create-nx-workspace go-workspace --preset=@naxodev/gonx \ - --type=go-blueprint \ - --framework=echo \ - --driver=sqlite \ - --addGoDotWork=true -``` - -## Template Types - -### Binary - -- Creates a standard Go application using gonx's application generator -- Simple `main.go` with basic structure -- Ready for immediate development with `nx build`, `nx serve`, etc. - -### Library - -- Creates a Go library using gonx's library generator -- Includes example library code and tests -- Configured for sharing and reuse - -### Go Blueprint - -- Uses [Go Blueprint](https://github.com/Melkeydev/go-blueprint) for advanced scaffolding -- Provides multiple web frameworks and database integrations -- Includes optional features like Docker, GitHub Actions, WebSockets, etc. -- Go Blueprint binary is included with the package - -## Project Structure - -### Binary/Library Output - -``` -my-go-project/ -├── main.go (or library code) -├── go.mod -├── go.sum -└── nx.json -``` - -### Go Blueprint Output - -The structure varies based on selected framework and features, but typically includes: - -``` -my-go-project/ -├── main.go -├── go.mod -├── go.sum -├── handlers/ -├── models/ -├── database/ -├── static/ -├── Dockerfile (if docker feature selected) -└── ... (additional files based on features) -``` - -## Notes - -- Creates a new Nx workspace with gonx pre-configured -- Sets up the workspace with Go support and inferred tasks -- Ready to use immediately for Go development -- Go Blueprint binary is bundled with the package -- Creates go.work file only when explicitly requested via the `addGoDotWork` option -- All template types support the full gonx toolchain (build, test, lint, etc.) - -## Integration with Nx - -After workspace creation, all standard Nx commands work immediately: - -```bash -# Build your project -nx build - -# Run your application -nx serve - -# Run tests -nx test - -# Lint code -nx lint - -# View project graph -nx graph -``` diff --git a/docs/gonx-docs/src/content/docs/getting-started/installation.md b/docs/gonx-docs/src/content/docs/getting-started/installation.md new file mode 100644 index 000000000..a44d4293e --- /dev/null +++ b/docs/gonx-docs/src/content/docs/getting-started/installation.md @@ -0,0 +1,90 @@ +--- +title: Install GoNx +description: How to install and configure @naxodev/gonx in your workspace. +--- + +import { Steps } from '@astrojs/starlight/components'; + +How to install `@naxodev/gonx` in an existing Nx workspace and register the +inference plugin. + +## Before you start + +- An **Nx 23.x** workspace (or later) +- **Node.js 20+** +- **Go** — a [stable release](https://go.dev/dl/) (1.18+ for multi-module + workspaces) + +Don't have a workspace yet? Create one with the gonx preset and skip to step 3: + +```bash +npx create-nx-workspace my-org --preset=@naxodev/gonx +``` + +## Steps + + +1. **Install the package** + +```bash +npm install @naxodev/gonx --save-dev +``` + +Or with Nx's built-in installer, which also runs any migrations: + +```bash +npx nx add @naxodev/gonx +``` + +2. **Register the inference plugin in `nx.json`** + + Add `@naxodev/gonx` to the `plugins` array: + + ```json + { + "plugins": ["@naxodev/gonx"] + } + ``` + + The plugin infers Nx projects from every `go.mod` matched by `**/go.mod`. + No per-project `project.json` is needed. + +3. **Verify the plugin is loaded** + + ```bash + npx nx show projects + ``` + + Every directory containing a `go.mod` should appear as an Nx project. If you + used the preset, your starter Go project will be listed. + + +## Configuration + +To customize inferred target names or disable dependency detection, use the +object form with `options`: + +```json +{ + "plugins": [ + { + "plugin": "@naxodev/gonx", + "options": { + "buildTargetName": "build", + "testTargetName": "test", + "skipGoDependencyCheck": false + } + } + ] +} +``` + +See the [plugin options reference](/guides/generators/options) for every +available option. + +## Next steps + +- [Quick start](/getting-started/quick-start) — create, run, test, and build a Go app +- [Create your first Go project](/tutorials/first-go-project) — a full tutorial walkthrough +- [Application generator](/guides/generators/application) — scaffold a Go application +- [Migrate to gonx 3.0.0](/community/migration) — coming from nx-go diff --git a/docs/gonx-docs/src/content/docs/getting-started/introduction.md b/docs/gonx-docs/src/content/docs/getting-started/introduction.md new file mode 100644 index 000000000..1da3f761f --- /dev/null +++ b/docs/gonx-docs/src/content/docs/getting-started/introduction.md @@ -0,0 +1,37 @@ +--- +title: Introduction +description: What is GoNx and what can it do for you? +--- + +GoNx is an [Nx](https://nx.dev/) plugin for [Go](https://go.dev/) development. It +brings the benefits of Nx — caching, affected-task detection, project graph +visualization, and generators — to Go projects without requiring hand-written +`project.json` targets. + +## What gonx does + +gonx infers build, serve, test, lint, tidy, and generate targets automatically +from every `go.mod` in your workspace. It builds the Nx project graph by +parsing Go source files with [tree-sitter](https://tree-sitter.github.io/) to +extract import statements and resolve them to Nx projects — no Go toolchain +required for graph computation. It also ships generators for scaffolding +applications, libraries, and [Go Blueprint](https://github.com/melkeydev/go-blueprint) +projects with web frameworks and database drivers. + +## Who it's for + +gonx is for teams and individuals who already use Nx (or want to) and have Go +projects in their workspace. It is a fork of +[@nx-go/nx-go](https://github.com/nx-go/nx-go), modernized for Nx 23 with +inferred tasks and a tree-sitter-based project graph. If you are migrating from +nx-go, see the [migration guide](/community/migration). + +## Where to go next + +- New to gonx? Start with the [quick start](/getting-started/quick-start). +- Adding gonx to an existing workspace? See + [install gonx](/getting-started/installation). +- Want a step-by-step walkthrough? Read + [create your first Go project](/tutorials/first-go-project). +- Curious how the project graph works? See + [how static analysis works](/understanding/static-analysis). diff --git a/docs/gonx-docs/src/content/docs/getting-started/quick-start.md b/docs/gonx-docs/src/content/docs/getting-started/quick-start.md new file mode 100644 index 000000000..2163f73a5 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/getting-started/quick-start.md @@ -0,0 +1,98 @@ +--- +title: Quick start +description: Get up and running with gonx in under a minute. +--- + +import { Steps } from '@astrojs/starlight/components'; + +Create a Go application with Nx, then run, test, and build it using targets that +gonx infers from `go.mod`. + +:::note +gonx is a fork of [@nx-go/nx-go](https://github.com/nx-go/nx-go), modernized for +Nx 23 with inferred tasks and a tree-sitter-based project graph. +::: + +## Before you start + +- **Node.js 20+** and an Nx 23.x workspace +- **Go** — a [stable release](https://go.dev/dl/) (1.18+ for multi-module + workspaces) + +gonx 3.x targets Nx 23.x: + +| Nx version | gonx version | +| ---------- | ------------ | +| 23.x | 3.x | + +## Steps + + +1. **Create a workspace with the gonx preset** + ```bash + npx create-nx-workspace go-workspace --preset=@naxodev/gonx + ``` + This scaffolds an Nx workspace with gonx registered and a starter Go project. + If you already have a workspace, install gonx into it instead: + ```bash + npx nx add @naxodev/gonx + ``` + +2. **Create a Go application** + + ```bash + cd go-workspace + npx nx g @naxodev/gonx:application my-go-app + ``` + + The generator creates a Go project with a `package main` entry point. gonx + detects the `go.mod` and infers `build`, `serve`, `test`, `lint`, `tidy`, and + `generate` targets. Pass `--template` to choose `standard`, `cli`, or `tui`. + See the [application generator guide](/guides/generators/application) for all + options. + +3. **Run the application** + + ```bash + npx nx serve my-go-app + ``` + + The `serve` target runs `go run` from the project root. See the + [serve executor guide](/guides/executors/serve). + +4. **Test the project** + + ```bash + npx nx test my-go-app + ``` + + The `test` target runs `go test`. See the + [test executor guide](/guides/executors/test). + +5. **Build the project** + ```bash + npx nx build my-go-app + ``` + The `build` target compiles an executable. See the + [build executor guide](/guides/executors/build). + + +## Verify + +List the projects Nx detected and the targets inferred for your application: + +```bash +npx nx show projects +npx nx show project my-go-app +``` + +`nx show project` lists the `build`, `serve`, `test`, `lint`, `tidy`, and +`generate` targets with no `project.json` file. Run `npx nx build my-go-app` a +second time to confirm caching — the second run is served from the Nx cache. + +## Next steps + +- [Create your first Go project](/tutorials/first-go-project) — a full walkthrough with explanations +- [Install GoNx](/getting-started/installation) — add gonx to an existing workspace +- [Plugin options](/guides/generators/options) — customize target names and tags +- [Migrate to gonx 3.0.0](/community/migration) — coming from nx-go diff --git a/docs/gonx-docs/src/content/docs/guides/executors/build.md b/docs/gonx-docs/src/content/docs/guides/executors/build.md new file mode 100644 index 000000000..a70160f1a --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/build.md @@ -0,0 +1,50 @@ +--- +title: Build executor +description: Compiles a Go program into an executable using the go build command. +--- + +The build executor compiles a Go program into an executable using `go build`. + +## Usage + +```bash +nx build my-go-app +``` + +## Options + +| Option | Type | Default | Description | +| ---------- | ------------------- | ------- | ---------------------------------------------------------------------------- | +| main | string | - | Relative path from the project root to the main.go file defining the binary. | +| compiler | go \| tinygo \| gow | go | The Go compiler to use. | +| outputPath | string | - | The output path of the resulting executable. | +| buildMode | string | - | The build mode to use. | +| env | object | - | Environment variables to set when running the executor. | +| flags | string[] | - | Flags to pass to the go compiler. | + +When `main` is set, the build runs from the directory containing that main.go file. When omitted, the build targets `./...` (all packages in the project tree). + +## Inferred target + +Inferred for projects containing a `main` package (applications). The plugin generates: + +```json +{ + "executor": "@naxodev/gonx:build", + "cache": true, + "dependsOn": ["generate"], + "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"], + "options": { + "outputPath": "dist/{projectRoot}/" + }, + "outputs": ["{options.outputPath}"] +} +``` + +The default `outputPath` resolves to `dist//`. Override it via the `outputPath` option. + +## Next steps + +- [Serve executor](/guides/executors/serve) +- [Test executor](/guides/executors/test) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/executors/generate.md b/docs/gonx-docs/src/content/docs/guides/executors/generate.md new file mode 100644 index 000000000..f8264e256 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/generate.md @@ -0,0 +1,42 @@ +--- +title: Generate executor +description: Runs code generation using the go generate command. +--- + +The generate executor runs code generation using `go generate ./...`, processing all `//go:generate` directives in the project tree. + +## Usage + +```bash +nx run my-go-project:generate +``` + +Use `nx run :generate` instead of `nx generate ` to avoid conflicts with Nx's native generator command. + +## Options + +| Option | Type | Default | Description | +| ------ | -------- | ------- | ------------------------------------------------------- | +| env | object | - | Environment variables to set when running the executor. | +| flags | string[] | - | Flags to pass to the go generate command. | + +## Inferred target + +Inferred for all Go projects (applications and libraries): + +```json +{ + "executor": "@naxodev/gonx:generate", + "cache": true, + "dependsOn": ["^generate"], + "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] +} +``` + +The `^generate` dependency means generate targets run after upstream project generate targets complete. + +## Next steps + +- [Build executor](/guides/executors/build) +- [Test executor](/guides/executors/test) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/executors/lint.md b/docs/gonx-docs/src/content/docs/guides/executors/lint.md new file mode 100644 index 000000000..f59974c14 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/lint.md @@ -0,0 +1,39 @@ +--- +title: Lint executor +description: Formats and lints a Go project. +--- + +The lint executor formats and lints a Go project. By default it runs `go fmt ./...`. + +## Usage + +```bash +nx lint my-go-project +``` + +## Options + +| Option | Type | Default | Description | +| ------ | -------- | ------- | ------------------------------------------- | +| linter | string | go fmt | The command to execute instead of `go fmt`. | +| args | string[] | - | Extra args passed to the linter. | + +When `linter` is set, the executor runs that command with `args` and `./...` appended, bypassing `go fmt`. + +## Inferred target + +Inferred for all Go projects (applications and libraries): + +```json +{ + "executor": "@naxodev/gonx:lint", + "cache": true, + "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] +} +``` + +## Next steps + +- [Test executor](/guides/executors/test) +- [Tidy executor](/guides/executors/tidy) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/executors/nx-release-publish.md b/docs/gonx-docs/src/content/docs/guides/executors/nx-release-publish.md new file mode 100644 index 000000000..ad8445d14 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/nx-release-publish.md @@ -0,0 +1,57 @@ +--- +title: nx-release-publish executor +description: Publishes a Go module to the Go proxy as part of the Nx release process. +--- + +The nx-release-publish executor publishes a Go module to the Go proxy (proxy.golang.org) by running `GOPROXY=proxy.golang.org go list -m @`. The version is resolved from the latest git tag matching the release tag pattern configured in `nx.json`. + +The manifest key in `executors.json` is `release-publish`. The inferred target name is `nx-release-publish`. + +## Usage + +```bash +nx nx-release-publish my-go-lib +``` + +Or through the Nx release pipeline: + +```bash +nx release --publish +``` + +## Options + +| Option | Type | Default | Description | +| ---------- | ------- | ------------ | ---------------------------------------------------------- | +| moduleRoot | string | project root | Path to the directory containing the go.mod file. | +| dryRun | boolean | false | When true, print the publish command without executing it. | + +The `NX_DRY_RUN` environment variable also triggers a dry run when set to `true`. + +## Inferred target + +Inferred for all Go projects (applications and libraries): + +```json +{ + "executor": "@naxodev/gonx:release-publish", + "options": { + "moduleRoot": "{projectRoot}" + }, + "configurations": { + "development": { + "dryRun": true + } + } +} +``` + +The `development` configuration sets `dryRun: true`, allowing test runs via `--configuration=development`. + +The default release tag pattern is `v{version}`. Override it in `nx.json` under `release.releaseTag.pattern`, which supports `{projectName}` and `{version}` placeholders. + +## Next steps + +- [Build executor](/guides/executors/build) +- [Plugin options](/guides/generators/options) +- [Quick start](/getting-started/quick-start) diff --git a/docs/gonx-docs/src/content/docs/guides/executors/serve.md b/docs/gonx-docs/src/content/docs/guides/executors/serve.md new file mode 100644 index 000000000..d47668ad2 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/serve.md @@ -0,0 +1,40 @@ +--- +title: Serve executor +description: Runs a Go application using the go run command. +--- + +The serve executor runs a Go application using `go run`. + +## Usage + +```bash +nx serve my-go-app +``` + +## Options + +| Option | Type | Default | Description | +| ------ | ------------------- | ------- | ---------------------------------------------------------------------------- | +| main | string | - | Relative path from the project root to the main.go file defining the binary. | +| cmd | go \| tinygo \| gow | go | The binary to use for running the application. | +| args | string[] | - | Extra args passed to the run command. | +| env | object | - | Environment variables to set when running the application. | + +When `main` is set, the serve runs from the directory containing that main.go file. When omitted, the serve targets `./...`. + +## Inferred target + +Inferred for projects containing a `main` package (applications). The target is continuous and not cached: + +```json +{ + "executor": "@naxodev/gonx:serve", + "continuous": true, + "options": {} +} +``` + +## Next steps + +- [Build executor](/guides/executors/build) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/executors/test.md b/docs/gonx-docs/src/content/docs/guides/executors/test.md new file mode 100644 index 000000000..29c452025 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/test.md @@ -0,0 +1,45 @@ +--- +title: Test executor +description: Runs tests for a Go project using the go test command. +--- + +The test executor runs Go tests using `go test ./...`. + +## Usage + +```bash +nx test my-go-project +``` + +## Options + +| Option | Type | Default | Description | +| ------------ | ------- | ------- | --------------------------------------------------------------------------- | +| cover | boolean | false | Enable coverage analysis. | +| coverProfile | string | - | Write a coverage profile to the file after all tests have passed. | +| race | boolean | false | Enable the race detector. | +| run | string | - | Run only tests matching this regular expression. | +| verbose | boolean | false | Enable verbose test output. | +| count | number | - | Run each test N times. | +| timeout | string | 10m | Panic if a test binary runs longer than this duration. Set to 0 to disable. | + +## Inferred target + +Inferred for all Go projects (applications and libraries): + +```json +{ + "executor": "@naxodev/gonx:test", + "cache": true, + "dependsOn": ["generate", "^build"], + "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] +} +``` + +The `^build` dependency means test targets run after upstream project build targets complete. + +## Next steps + +- [Build executor](/guides/executors/build) +- [Lint executor](/guides/executors/lint) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/executors/tidy.md b/docs/gonx-docs/src/content/docs/guides/executors/tidy.md new file mode 100644 index 000000000..29d0b1f9a --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/executors/tidy.md @@ -0,0 +1,35 @@ +--- +title: Tidy executor +description: Runs go mod tidy to sync go.mod with the project source code. +--- + +The tidy executor runs `go mod tidy` to ensure the go.mod file matches the project source code. + +## Usage + +```bash +nx tidy my-go-project +``` + +## Options + +| Option | Type | Default | Description | +| ------ | -------- | ------- | ----------------------------------- | +| args | string[] | - | Extra args passed to `go mod tidy`. | + +## Inferred target + +Inferred for all Go projects (applications and libraries): + +```json +{ + "executor": "@naxodev/gonx:tidy", + "cache": true, + "inputs": ["{projectRoot}/go.mod", "{projectRoot}/go.sum", "{projectRoot}/**/*.{go}"] +} +``` + +## Next steps + +- [Lint executor](/guides/executors/lint) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/generators/application.md b/docs/gonx-docs/src/content/docs/guides/generators/application.md new file mode 100644 index 000000000..0ccf57b57 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/generators/application.md @@ -0,0 +1,34 @@ +--- +title: Application generator +description: Generates a Go application and registers it as an Nx project through the gonx inference plugin. +--- + +Generates a Go application under the given directory and registers it as an Nx project through the gonx inference plugin. Aliased as `app`. + +## Usage + +```bash +nx g @naxodev/gonx:application +``` + +## Options + +| Option | Type | Default | Description | +| ---------- | ---------------------------- | ---------- | --------------------------------------------------------------------------- | +| directory | string | _required_ | Directory of the new application. Taken from the first positional argument. | +| name | string | - | Name of the application. Must match `^[a-zA-Z][^:]*$`. | +| template | `standard` \| `cli` \| `tui` | `standard` | Application template to generate. | +| tags | string | - | Tags to add to the application (used for linting). | +| skipFormat | boolean | `false` | Skip formatting files. | + +## Notes + +- Runs the init generator first to register the inference plugin in `nx.json`. +- Creates a `go.mod` for the project unless the template already includes one. Adds the project to `go.work` when a Go workspace is present. +- Inferred targets for applications: `build`, `serve`, `test`, `lint`, `tidy`, `generate`, `nx-release-publish`. Application detection requires a `main.go` containing `package main` and `func main(`, or a `cmd/` directory. + +## Next steps + +- [Library generator](/guides/generators/library) +- [Build executor](/guides/executors/build) +- [Serve executor](/guides/executors/serve) diff --git a/docs/gonx-docs/src/content/docs/guides/generators/go-blueprint.md b/docs/gonx-docs/src/content/docs/guides/generators/go-blueprint.md new file mode 100644 index 000000000..f6d9d7273 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/generators/go-blueprint.md @@ -0,0 +1,40 @@ +--- +title: Go Blueprint generator +description: Generates a Go application by wrapping the @melkeydev/go-blueprint CLI. +--- + +Generates a Go application by wrapping the `@melkeydev/go-blueprint` CLI, which is bundled with this package. Scaffolds a project from a selected web framework, database driver, and optional advanced features. + +## Usage + +```bash +nx g @naxodev/gonx:go-blueprint +``` + +## Options + +| Option | Type | Default | Description | +| ------------ | ------------------------------------------------------------------------------------------ | ---------- | -------------------------------------------------------------------------------------- | +| directory | string | _required_ | Directory of the new application. Taken from the first positional argument. | +| name | string | - | Name of the application. Must match `^[a-zA-Z][^:]*$`. | +| tags | string | - | Tags to add to the project (used for linting). | +| skipFormat | boolean | `false` | Skip formatting files. | +| addGoDotWork | boolean | `false` | Add this project to `go.work`. | +| framework | `chi` \| `gin` \| `fiber` \| `gorilla/mux` \| `httprouter` \| `standard-library` \| `echo` | _required_ | Web framework. | +| driver | `mysql` \| `postgres` \| `sqlite` \| `mongo` \| `redis` \| `scylla` \| `none` | _required_ | Database driver. | +| git | `commit` \| `stage` \| `skip` | _required_ | Git handling. | +| feature | array | - | Advanced features: `react`, `htmx`, `githubaction`, `websocket`, `tailwind`, `docker`. | + +## Notes + +- The `@melkeydev/go-blueprint` binary is resolved from the bundled npm dependency; no separate installation is required. +- Runs the init generator first to register the inference plugin. Adds the project to `go.work` when `addGoDotWork` is set and a Go workspace is supported. +- Removes `.air.toml`, `README.md`, and `Makefile` from the generated output. +- The `react` feature embeds frontend code inside the Go project directory, which Nx's project graph does not detect as a separate project. +- Inferred targets for the resulting application: `build`, `serve`, `test`, `lint`, `tidy`, `generate`, `nx-release-publish`. + +## Next steps + +- [Application generator](/guides/generators/application) +- [Build executor](/guides/executors/build) +- [Serve executor](/guides/executors/serve) diff --git a/docs/gonx-docs/src/content/docs/guides/generators/init.md b/docs/gonx-docs/src/content/docs/guides/generators/init.md new file mode 100644 index 000000000..52b9f0699 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/generators/init.md @@ -0,0 +1,30 @@ +--- +title: Init generator +description: Registers the gonx inference plugin in an Nx workspace and optionally creates a go.work file. +--- + +Registers the gonx inference plugin in `nx.json` and optionally creates a `go.work` file. Hidden from `nx list` and invoked automatically by the other generators. + +## Usage + +```bash +nx g @naxodev/gonx:init +``` + +## Options + +| Option | Type | Default | Description | +| ------------ | ------- | ------- | ------------------------------------------------------------ | +| skipFormat | boolean | `false` | Skip formatting files. | +| addGoDotWork | boolean | `false` | Create a `go.work` file and add Go config to shared globals. | + +## Notes + +- `go.work` creation requires a locally installed Go toolchain that supports Go workspaces. +- Invoked by the application, library, and go-blueprint generators (and indirectly by the preset generator) with `skipFormat: true`. + +## Next steps + +- [Application generator](/guides/generators/application) +- [Library generator](/guides/generators/library) +- [Plugin options](/guides/generators/options) diff --git a/docs/gonx-docs/src/content/docs/guides/generators/library.md b/docs/gonx-docs/src/content/docs/guides/generators/library.md new file mode 100644 index 000000000..585092043 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/generators/library.md @@ -0,0 +1,33 @@ +--- +title: Library generator +description: Generates a Go library and registers it as an Nx project through the gonx inference plugin. +--- + +Generates a Go library under the given directory and registers it as an Nx project through the gonx inference plugin. Aliased as `lib`. + +## Usage + +```bash +nx g @naxodev/gonx:library +``` + +## Options + +| Option | Type | Default | Description | +| ---------- | ------- | ---------- | ----------------------------------------------------------------------- | +| directory | string | _required_ | Directory of the new library. Taken from the first positional argument. | +| name | string | - | Name of the library. Must match `^[a-zA-Z][^:]*$`. | +| tags | string | - | Tags to add to the library (used for linting). | +| skipFormat | boolean | `false` | Skip formatting files. | + +## Notes + +- Runs the init generator first to register the inference plugin in `nx.json`. +- Always creates a `go.mod` for the project. Adds the project to `go.work` when a Go workspace is present. +- Inferred targets for libraries: `test`, `lint`, `tidy`, `generate`, `nx-release-publish`. Libraries do not infer `build` or `serve`. + +## Next steps + +- [Application generator](/guides/generators/application) +- [Test executor](/guides/executors/test) +- [Lint executor](/guides/executors/lint) diff --git a/docs/gonx-docs/src/content/docs/guides/generators/options.md b/docs/gonx-docs/src/content/docs/guides/generators/options.md new file mode 100644 index 000000000..78e80a104 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/generators/options.md @@ -0,0 +1,57 @@ +--- +title: Plugin options +description: GoPluginOptions reference for the @naxodev/gonx plugin registration in nx.json. +--- + +Reference for the `GoPluginOptions` accepted by the `@naxodev/gonx` plugin registration in `nx.json`. The plugin infers Nx projects from every `go.mod` matched by `**/go.mod`. + +## Usage + +String form (all defaults apply): + +```json +{ + "plugins": ["@naxodev/gonx"] +} +``` + +Object form: + +```json +{ + "plugins": [ + { + "plugin": "@naxodev/gonx", + "options": { + "buildTargetName": "build", + "skipGoDependencyCheck": true + } + } + ] +} +``` + +## Options + +| Option | Type | Default | Description | +| ------------------------ | ------- | -------------------- | ------------------------------------------------------------------- | +| buildTargetName | string | `build` | Name of the inferred build target. Inferred only for applications. | +| testTargetName | string | `test` | Name of the inferred test target. | +| runTargetName | string | `serve` | Name of the inferred run target. Inferred only for applications. | +| tidyTargetName | string | `tidy` | Name of the inferred tidy target. | +| lintTargetName | string | `lint` | Name of the inferred lint target. | +| generateTargetName | string | `generate` | Name of the inferred generate target. | +| releasePublishTargetName | string | `nx-release-publish` | Name of the inferred release publish target. | +| tagName | string | - | Tag applied to every inferred Go project. | +| skipGoDependencyCheck | boolean | `false` | Disables Go project dependency detection in the Nx workspace graph. | + +## Notes + +- Applications are projects with a `main.go` containing `package main` and `func main(`, or a `cmd/` directory. All other Go projects are treated as libraries. +- `buildTargetName` and `runTargetName` only affect applications; libraries never infer build or run targets regardless of these options. + +## Next steps + +- [Application generator](/guides/generators/application) +- [Library generator](/guides/generators/library) +- [Init generator](/guides/generators/init) diff --git a/docs/gonx-docs/src/content/docs/guides/generators/preset.md b/docs/gonx-docs/src/content/docs/guides/generators/preset.md new file mode 100644 index 000000000..d301bf084 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/guides/generators/preset.md @@ -0,0 +1,45 @@ +--- +title: Preset generator +description: Preset used by create-nx-workspace to scaffold a new Nx workspace with gonx pre-configured. +--- + +Preset used by `create-nx-workspace` to scaffold a new Nx workspace with gonx pre-configured. Delegates to the application, library, or go-blueprint generator based on the selected `type`. + +## Usage + +```bash +npx create-nx-workspace --preset=@naxodev/gonx +``` + +## Options + +| Option | Type | Default | Description | +| ------------ | --------------------------------------- | ---------- | ----------------------------------------------------------------------- | +| type | `binary` \| `library` \| `go-blueprint` | `binary` | Template type to generate. Required. | +| directory | string | _required_ | Directory of the new project. Taken from the first positional argument. | +| name | string | - | Name of the project. Must match `^[a-zA-Z][^:]*$`. | +| tags | string | - | Tags to add to the project (used for linting). | +| skipFormat | boolean | `false` | Skip formatting files. | +| addGoDotWork | boolean | `false` | Add a `go.work` file to the project. | + +### go-blueprint options + +When `type` is `go-blueprint`, the following options are also required: + +| Option | Type | Default | Description | +| --------- | ------------------------------------------------------------------------------------------ | ---------- | -------------------------------------------------------------------------------------- | +| framework | `chi` \| `gin` \| `fiber` \| `gorilla/mux` \| `httprouter` \| `standard-library` \| `echo` | _required_ | Web framework. | +| driver | `mysql` \| `postgres` \| `sqlite` \| `mongo` \| `redis` \| `scylla` \| `none` | _required_ | Database driver. | +| git | `commit` \| `stage` \| `skip` | _required_ | Git handling. | +| feature | array | - | Advanced features: `react`, `htmx`, `githubaction`, `websocket`, `tailwind`, `docker`. | + +## Notes + +- `type=binary` delegates to the application generator; `type=library` delegates to the library generator; `type=go-blueprint` delegates to the go-blueprint generator. +- When invoked programmatically without go-blueprint values, the preset applies `framework=gin`, `driver=none`, `git=skip`, `feature=[]`. + +## Next steps + +- [Application generator](/guides/generators/application) +- [Library generator](/guides/generators/library) +- [Go Blueprint generator](/guides/generators/go-blueprint) diff --git a/docs/gonx-docs/src/content/docs/index.mdx b/docs/gonx-docs/src/content/docs/index.mdx index 3b7cc4168..7ebcf587c 100644 --- a/docs/gonx-docs/src/content/docs/index.mdx +++ b/docs/gonx-docs/src/content/docs/index.mdx @@ -1,18 +1,14 @@ --- title: GoNx documentation -description: Nx plugin for Go Development +description: Nx plugin for Go development template: splash hero: - tagline: A Nx plugin for Go development + tagline: An Nx plugin for Go development --- import { Card, CardGrid } from '@astrojs/starlight/components'; - - Join our [Discord Server](https://discord.gg/zjDCGpKP2S) to chat with the - community and get support. -
@@ -21,66 +17,73 @@ import { Card, CardGrid } from '@astrojs/starlight/components'; srcset="https://pub-2030b241eb284b5291e3e59724e55a66.r2.dev/gonx.svg" /> gonx - Nx plugin for Go/Golang
- A modern Nx plugin for [Go/Golang](/quick-start) development with full Nx integration, - inferred tasks, and official Go command support. + An Nx plugin for [Go](https://go.dev/) development. gonx infers build, serve, + test, lint, tidy, and generate targets from each go.mod, builds + the project graph from Go imports, and ships generators for applications, libraries, + and Go Blueprint projects. Available on [npm](https://www.npmjs.com/package/@naxodev/gonx).
- - GoNx is open source and welcomes contributions. Check out our [GitHub - repository](https://github.com/naxodev/oss/tree/main/packages/gonx). + + gonx is MIT licensed and developed on + [GitHub](https://github.com/naxodev/oss/tree/main/packages/gonx). Report + bugs and request features in the [issue + tracker](https://github.com/naxodev/oss/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc). + + + Join the [Discord server](https://discord.gg/zjDCGpKP2S) to ask questions + and get help.
--- -## ✨ Key Features +## Key features
- 🚀 -

Modern Nx Integration

+

Inferred tasks

- Built for the latest Nx features with full support for inferred tasks. + gonx detects each go.mod and infers build, serve, test, lint, + tidy, and generate targets automatically — no hand-written project.json + files.

{' '} +{' '} +
- 🐹 -

Advanced Go boilerplate generators

+

Project graph from static analysis

- Provides a comprehensive list of generators to reduce boilerplate time, - including a Go Blueprint integration. + A tree-sitter parser reads Go imports and go.mod files to build + Nx project dependencies.

{' '} -
- 📦 -

Monorepo Ready

-

- Designed for large-scale monorepo development. -

-
+
+

Generators

+

+ Scaffold applications, libraries, and Go Blueprint projects with web + frameworks and database drivers. +

+
---
-

Ready to Get Started?

-

- Choose your path and start building amazing projects today -

+

Get started

diff --git a/docs/gonx-docs/src/content/docs/migration.md b/docs/gonx-docs/src/content/docs/migration.md deleted file mode 100644 index eac3bc477..000000000 --- a/docs/gonx-docs/src/content/docs/migration.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: Migration from nx-go -description: Guide for migrating from the original nx-go plugin to GoNx ---- - -This guide helps you migrate from the original [@nx-go/nx-go](https://github.com/nx-go/nx-go) plugin to GoNx. - -:::caution -Although GoNx works well as a drop-in replacement for nx-go in most cases, our philosophy and core implementation have changed since the first fork, which may cause some workflows designed for nx-go not to work with GoNx. -::: - -## Overview of Changes - -GoNx is a modernized fork of nx-go with significant architectural changes: - -### Major Breaking Changes - -1. **Modern Nx-only**: Requires Nx 21.x or later -2. **No project.json generation**: Uses inferred tasks instead -3. **Changed command execution**: Runs from project root instead of workspace root -4. **Removed go.work creation**: Now opt-in via configuration -5. **Removed legacy generators**: `convert-to-one-module` is no longer available - -### New Features - -1. **Inferred tasks**: Automatic task detection and configuration -2. **Cacheable operations**: All tasks are properly cached -3. **CreateNodesV2**: Latest Nx project detection API -4. **Version Actions**: Proper Go versioning with Nx Release -5. **Publish executor**: Automated registry publishing - -## Migration Steps - -### Step 1: Prerequisites - -Before starting the migration: - -1. **Upgrade Nx**: Ensure you're on Nx 21.x or later -2. **Update Go**: Use a stable Go version (1.21+ recommended) -3. **Backup your workspace**: Create a backup before making changes -4. **Review project structure**: Understand your current setup - -### Step 2: Remove nx-go Plugin - -Remove the original nx-go plugin: - -```bash -npm uninstall @nx-go/nx-go -# or -pnpm remove @nx-go/nx-go -# or -yarn remove @nx-go/nx-go -``` - -### Step 3: Install GoNx - -Install the GoNx plugin: - -```bash -npm install @naxodev/gonx -# or -pnpm add @naxodev/gonx -# or -yarn add @naxodev/gonx -``` - -### Step 4: Update Nx Configuration - -Update your `nx.json` to use GoNx: - -```json -{ - "plugins": [ - { - "plugin": "@naxodev/gonx", - "options": { - "addGoDotWork": false - } - } - ] -} -``` - -Remove any nx-go specific configuration. - -### Step 5: Handle project.json Files - -GoNx uses inferred tasks, so you can remove `project.json` files from your Go projects: - -:::caution -Keep `project.json` files for non-Go projects or if you need custom task configuration. -::: - -```bash -# Remove project.json files from Go projects -rm apps/my-go-app/project.json -rm libs/my-go-lib/project.json -``` - -:::tip -The inferred target configurations are available in the [executor's](/gonx/executors/generate) documentation in case modifications are needed. -::: - -### Step 6: Update Scripts and CI - -Update any scripts or CI configurations that reference nx-go: - -#### Package.json Scripts - -```json -{ - "scripts": { - "build:go": "nx run-many --target=build --projects=tag:go", - "test:go": "nx run-many --target=test --projects=tag:go" - } -} -``` - -#### CI Configuration - -Update your CI to use the new executors and ensure Go is available in the environment. - -## Common Migration Issues - ---- - -### Issue: Projects Named Changed - -**Problem**: GoNx changed how project names are inferred - -**Solution**: -While nx-go uses the given name for the projects or the final segment of the path as the name, GoNx uses the entire path as the project name. - -Although this can make commands longer, it has two main benefits: - -- Removes the disambiguation name problem. -- Aligns perfectly with the Go standard for multi-module repository tag creation. - -[Reference](https://go.dev/doc/modules/managing-source) - -### Issue: Tasks Not Found - -**Problem**: Nx doesn't recognize Go project tasks. - -**Solution**: - -1. Ensure `go.mod` files exist in your Go projects -2. Clear Nx cache: `nx reset` -3. Verify plugin configuration in `nx.json` - -### Issue: Project Graph Issues - -**Problem**: Project dependencies aren't detected correctly. - -**Solution**: - -1. Ensure Go imports are correctly structured -2. Use proper module paths -3. Clear cache and regenerate: `nx reset && nx graph` - -## Post-Migration Testing - -After migration, verify everything works: - -### 1. Project Detection - -```bash -nx show projects -``` - -### 2. Task Execution - -```bash -nx build my-go-app -nx test my-go-lib -nx lint my-go-app -``` - -### 3. Project Graph - -```bash -nx graph -``` - -### 4. Caching - -```bash -nx build my-go-app -nx build my-go-app # Should use cache -``` - -## Getting Help - -If you encounter issues during migration: - -1. **Check documentation**: Review GoNx documentation thoroughly -2. **Search issues**: Look for similar issues on GitHub -3. **Join Discord**: Get real-time help on our [Discord server](https://discord.gg/zjDCGpKP2S) -4. **Create issue**: Report bugs or request help on GitHub diff --git a/docs/gonx-docs/src/content/docs/quick-start.md b/docs/gonx-docs/src/content/docs/quick-start.md deleted file mode 100644 index 4ba920cd0..000000000 --- a/docs/gonx-docs/src/content/docs/quick-start.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -title: Quick Start -description: Get up and running with OSS workspace plugins ---- - -
- - - gonx - Nx plugin for Go/Golang - -

GoNx

-

A modern Nx plugin for Go/Golang development

-
- -GoNx - A very opinionated Nx plugin for Go/Golang - -The philosophy of gonx is to generate a non-invasive tooling to work with Go and Nx, heavily relying on inferred tasks and modern Nx features. - -:::note -This project is a fork of [@nx-go/nx-go](https://github.com/nx-go/nx-go). Kudos to the original maintainers. We've built upon their excellent foundation. -::: - -## Prerequisites - -Before getting started, ensure you have: - -- **Node.js** (version 18 or later) -- **npm**, **pnpm**, or **yarn** package manager -- **Nx CLI** (`npm install -g nx` or `npm install -g @nx/cli`) - -For GoNx specifically: - -- **Go** ([stable version](https://go.dev/dl/)) installed on your machine - -## Compatibility - -gonx is compatible with the following Nx versions: - -| Nx Version | gonx Version | -| ---------- | ----------------- | -| 21.x | >=^1.0.0 <=^2.0.0 | - -:::caution -This plugin is only tested on [stable versions of Go](https://go.dev/dl/); older versions do not receive support. However, you can expect a fair degree of compatibility. Please note that multi-module Go workspaces require Go 1.18 or later. -::: - -## Getting started - -### Option 1: Create a New Workspace with GoNx - -If you want to start a new workspace focused on Go development: - -```bash -npx create-nx-workspace go-workspace --preset=@naxodev/gonx -``` - -This will create a new Nx workspace pre-configured with GoNx. - -### Option 2: Add to Existing Workspace - -If you have an existing Nx workspace and want to add our plugins: - -#### Add GoNx - -```bash -nx add @naxodev/gonx -``` - -## Your First Project - -### Create a Go Application - -```bash -nx g @naxodev/gonx:application my-go-app -``` - -### Create a Go Library - -```bash -nx g @naxodev/gonx:library my-go-lib -``` - -## Common Commands - -Once you have projects set up, here are the most common commands you'll use: - -### Building Projects - -```bash -# Build a Go application -nx build my-go-app -``` - -### Running Projects - -```bash -# Run a Go application -nx serve my-go-app -``` - -### Testing Projects - -```bash -# Test a Go project -nx test my-go-app -``` - -## Generators & executors - -### Generators - -| Generator | Description | -| -------------------------------------------- | --------------------------------------------- | -| [`application`](../generators/application) | Generate a Go application | -| [`go-blueprint`](../generators/go-blueprint) | Generate Go applications using Go Blueprint | -| [`library`](../generators/library) | Generate a Go library | -| [`init`](../generators/init) | Initialize gonx in an existing workspace | -| [`preset`](../generators/preset) | Preset generator for creating a new workspace | - -### Executors - -| Executor | Description | -| ------------------------------------------------------- | ------------------------------------------------- | -| [`build`](../executors/build) | Build a Go project | -| [`generate`](../executors/generate) | Run code generation using go generate | -| [`lint`](../executors/lint) | Format and lint a Go project | -| [`serve`](../executors/serve) | Run a Go application | -| [`test`](../executors/test) | Run tests of a Go project | -| [`tidy`](../executors/tidy) | Ensures go.mod file matches a project source code | -| [`nx-release-publish`](../executors/nx-release-publish) | Lists the module in the Go registry | - -:::tip -You can run `nx list @naxodev/gonx` to view the list of plugin capabilities. -::: - -Need more customization? See our [plugin configuration options](./docs/options.md). - -#### Release Configuration - -GoNx supports Nx's release process with Go's versioning conventions. We automatically set up project names to match their directory paths, which ensures compatibility with Go's release tagging convention (`projectRoot/vx.x.x`). - -To configure your workspace for releasing Go modules, add a configuration like this to your `nx.json`: - -```json -{ - "release": { - "projectsRelationship": "independent", - "projects": ["your-go-project"], - "releaseTagPattern": "{projectName}/v{version}", // important! this is the Go release tag pattern - "changelog": { - ... - }, - "version": { - "useLegacyVersioning": false, // important! this means that we are using the plugin version actions - ... - }, - } -} -``` - -Key configuration points: - -- `releaseTagPattern`: Set to `{projectName}/v{version}` to create Go-compatible tags (e.g., `apps/myapp/v1.2.3`) -- `projectName`: With gonx, this is the full path to your project, not just the directory name - -See the [nx-release-publish executor docs](./docs/executors/nx-release-publish.md) for more information. - -## Contributors - -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): - - - - - - - - - - - - - -
- - Nacho Vazquez
- Nacho Vazquez -

- 🐛 - 💻 - 📖 - 💡 - 🤔 - 🧑‍🏫 - 🚧 - 📆 - 👀 -
- - Wenzel
- Wenzel -

- 💻 -
- - Miguel
- Miguel -

- 💻 -
- - Miguel
- Abel -

- 💻 - 📖 -
- -## Acknowledgements - -This project is a fork of [nx-go](https://github.com/nx-go/nx-go), a plugin for Nx that provides tools for building Go applications. Most credit goes to the original maintainers of nx-go - we've built upon their excellent foundation to modernize the plugin for the latest Nx features. - -We're also inspired by the work done by other Nx Champions: - -- -- - -## Community - -We value community contributions and feedback. Here's how you can get involved: - -- **Discord**: Join our [Discord Server](https://discord.gg/zjDCGpKP2S) for real-time discussions -- **GitHub**: Contribute to our [open source repository](https://github.com/naxodev/oss/tree/main/packages/gonx) -- **Issues**: Report bugs and request features through [GitHub Issues](https://github.com/naxodev/oss/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen) - -## Getting Support - -If you need help: - -1. Check the documentation -2. Search existing GitHub issues -3. Join our Discord community for quick questions -4. Create a new GitHub issue for bugs or feature requests - -Let's build something amazing together! 🚀 diff --git a/docs/gonx-docs/src/content/docs/reference/README.md b/docs/gonx-docs/src/content/docs/reference/README.md new file mode 100644 index 000000000..c8db0c678 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/reference/README.md @@ -0,0 +1,10 @@ +--- +editUrl: false +next: false +prev: false +title: "@naxodev/gonx" +--- + +## Variables + +- [export=](/reference/variables/export/) diff --git a/docs/gonx-docs/src/content/docs/reference/variables/export=.md b/docs/gonx-docs/src/content/docs/reference/variables/export=.md new file mode 100644 index 000000000..bbda3c46c --- /dev/null +++ b/docs/gonx-docs/src/content/docs/reference/variables/export=.md @@ -0,0 +1,10 @@ +--- +editUrl: false +next: false +prev: false +title: "export=" +--- + +> `const` **export=**: `NxPlugin` + +Defined in: [packages/gonx/src/index.ts:5](https://github.com/naxodev/oss/blob/main/packages/gonx/src/index.ts#L5) diff --git a/docs/gonx-docs/src/content/docs/tutorials/first-go-project.md b/docs/gonx-docs/src/content/docs/tutorials/first-go-project.md new file mode 100644 index 000000000..830d62da9 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/tutorials/first-go-project.md @@ -0,0 +1,139 @@ +--- +title: Create your first Go project +description: How to create, run, test, and build a Go project with Nx and gonx. +--- + +import { Steps } from '@astrojs/starlight/components'; + +In this tutorial we'll create a Go application with Nx, then run, test, and build +it using targets that gonx infers from `go.mod`. Along the way we'll see how Nx +caching and the project graph work with Go projects. + +## Before we start + +We need: + +- **Node.js 20+** and an **Nx 23.x** workspace +- **Go** — a [stable release](https://go.dev/dl/) (1.18+ for multi-module + workspaces) + +gonx 3.x targets Nx 23.x: + +| Nx version | gonx version | +| ---------- | ------------ | +| 23.x | 3.x | + +:::note +gonx is a fork of [@nx-go/nx-go](https://github.com/nx-go/nx-go), modernized for +Nx 23 with inferred tasks and a tree-sitter-based project graph. +::: + +## Steps + + +1. **Create a workspace with the gonx preset** + +We'll start by creating a fresh Nx workspace with gonx pre-configured: + +```bash +npx create-nx-workspace go-workspace --preset=@naxodev/gonx +``` + +This scaffolds an Nx workspace with gonx registered in `nx.json` and a +starter Go project. If you already have a workspace, install gonx into it +instead: + +```bash +npx nx add @naxodev/gonx +``` + +See [install gonx](/getting-started/installation) for details. + +2. **Create a Go application** + + Now we'll generate a Go application: + + ```bash + cd go-workspace + npx nx g @naxodev/gonx:application my-go-app + ``` + + The generator creates a Go project with a `package main` entry point and a + `go.mod` file. gonx detects the `go.mod` and automatically infers `build`, + `serve`, `test`, `lint`, `tidy`, and `generate` targets — no `project.json` + needed. We can pass `--template` to choose `standard`, `cli`, or `tui`. See + the [application generator guide](/guides/generators/application) for all + options. + +3. **Run the application** + + Let's run it: + + ```bash + npx nx serve my-go-app + ``` + + The `serve` target runs `go run` from the project root. It's a continuous + target, so it stays running until we stop it. See the + [serve executor guide](/guides/executors/serve). + +4. **Test the project** + + We can run the project's tests with: + + ```bash + npx nx test my-go-app + ``` + + The `test` target runs `go test ./...`. Because the target is cached, running + it again with no source changes will return instantly from the Nx cache. See + the [test executor guide](/guides/executors/test). + +5. **Build the project** + + Finally, let's build an executable: + + ```bash + npx nx build my-go-app + ``` + + The `build` target compiles a binary and outputs it to + `dist//`. See the + [build executor guide](/guides/executors/build). + + +## Verify + +Let's confirm Nx detected our project and inferred the right targets: + +```bash +npx nx show projects +npx nx show project my-go-app +``` + +`nx show project` lists the `build`, `serve`, `test`, `lint`, `tidy`, and +`generate` targets — all inferred, with no `project.json` file. Run +`npx nx build my-go-app` a second time to see Nx caching in action: the second +run is served from the cache and completes almost instantly. + +## Explore the project graph + +gonx builds the Nx project graph by parsing Go imports with tree-sitter. Let's +visualize the dependencies: + +```bash +npx nx graph +``` + +This opens the Nx project graph UI in your browser. If we add a library and +import it from our application, the graph will show the dependency edge — even +without `go.work`. See [how static analysis works](/understanding/static-analysis) +to learn how gonx resolves imports to Nx projects. + +## Next steps + +- [Application generator](/guides/generators/application) — all options including templates and tags +- [Library generator](/guides/generators/library) — scaffold a reusable Go package +- [Plugin options](/guides/generators/options) — customize target names and tags +- [How static analysis works](/understanding/static-analysis) — the tree-sitter project graph +- [Migrate to gonx 3.0.0](/community/migration) — coming from nx-go diff --git a/docs/gonx-docs/src/content/docs/understanding/static-analysis.md b/docs/gonx-docs/src/content/docs/understanding/static-analysis.md new file mode 100644 index 000000000..c7836f2c4 --- /dev/null +++ b/docs/gonx-docs/src/content/docs/understanding/static-analysis.md @@ -0,0 +1,117 @@ +--- +title: How static analysis works +description: Why gonx uses tree-sitter to build the Nx project graph from Go source. +--- + +gonx builds the Nx project graph by parsing Go source files directly with +[tree-sitter](https://tree-sitter.github.io/). This approach does not require Go +to be installed, which means `nx graph` and affected-task detection work even in +environments without a Go toolchain. + +## Why tree-sitter + +A Go toolchain is not always available in every environment that runs Nx — CI +runners, remote caches, or containers may have Node but not Go. Parsing Go +source with tree-sitter lets gonx extract import statements and build the +project graph without invoking `go list` or any external process. The parser is +a WebAssembly binary loaded from the `web-tree-sitter` and `tree-sitter-go` +packages, so it runs anywhere Node runs. + +## How the graph is built + +The dependency detection runs in four stages: + +1. **Module discovery** — gonx scans all Nx projects for `go.mod` files and + extracts module paths and replace directives. Each `go.mod` defines a Go + module; its module path is the key used to resolve imports. + +2. **Import extraction** — `.go` files are parsed with tree-sitter to extract + `import` statements. `vendor/` and `testdata/` directories are excluded. + +3. **Dependency resolution** — imports are resolved to Nx projects using + longest-prefix matching. For example, importing + `github.com/myorg/shared/utils` resolves to the project whose `go.mod` + declares `module github.com/myorg/shared`. + +4. **Replace directives** — `replace` directives in `go.mod` are scoped + per-project. A replace directive in one project's `go.mod` only affects that + project's imports, matching Go's own module resolution semantics. + +## Build constraints + +gonx honors `//go:build` and legacy `// +build` constraints. The dependency +graph is computed against the host platform's `GOOS`/`GOARCH` — a file gated to +a different platform contributes no edges on the host. + +Supported in the constraint expression: + +- `//go:build` modern boolean form: `&&`, `||`, `!`, parentheses +- `// +build` legacy form (space-separated terms = OR, comma-separated within a + term = AND, `!` per-term negation, multiple lines AND'd) +- `unix` pseudo-tag (matches Linux, Darwin, the BSDs, Solaris, AIX, and the + full set Go ships in `internal/syslist.UnixOS`) +- `GOOS` values (`linux`, `darwin`, `windows`, …) and `GOARCH` values + (`amd64`, `arm64`, `386`, …) +- User-defined tags, plus `cgo` and `go1.N` policy + +Filename-based suffixes are also honored, matching Go's `go/build` algorithm: +`name_.go`, `name_.go`, `name__.go`, and any of +those with a trailing `_test` before `.go`. Note that `unix` is recognized only +as an in-source build tag, **not** as a filename suffix — Go itself doesn't +treat `foo_unix.go` as unix-gated, and neither does gonx. + +### Edge-case behavior + +- `go1.X` version tags evaluate to `true` by default (no Go compiler is handy to + consult; over-including is safer than under-including for graph purposes). +- The `cgo` pseudo-tag evaluates to `false` by default — static analysis never + invokes cgo. +- A malformed constraint expression falls back to "include the file" rather than + failing graph construction. + +## Limitations + +- **No cgo support**: the `import "C"` pseudo-import is filtered out. +- **No dynamic imports**: only static `import` statements are detected. + +## Disabling dependency detection + +To disable Go dependency detection entirely, set +`skipGoDependencyCheck: true` in the plugin options: + +```json +{ + "plugins": [ + { + "plugin": "@naxodev/gonx", + "options": { + "skipGoDependencyCheck": true + } + } + ] +} +``` + +See the [plugin options reference](/guides/generators/options) for all +configuration options. + +## Troubleshooting + +### Dependencies not detected + +1. Verify both projects have `go.mod` files. +2. Check that the module paths match the import statements. +3. Ensure the importing project has a `replace` directive pointing to the local + project (required when not using `go.work`). + +### Debugging + +```bash +NX_VERBOSE_LOGGING=true nx graph +``` + +## Next steps + +- [Plugin options](/guides/generators/options) — `skipGoDependencyCheck` and other settings +- [Quick start](/getting-started/quick-start) — see the project graph in action +- [Contributing](/community/contributing) — how to contribute to gonx diff --git a/docs/gonx-docs/src/env.d.ts b/docs/gonx-docs/src/env.d.ts new file mode 100644 index 000000000..4ca6d2689 --- /dev/null +++ b/docs/gonx-docs/src/env.d.ts @@ -0,0 +1,16 @@ +/// + +declare module 'virtual:starlight/components/Search' { + const Search: typeof import('@astrojs/starlight/components').Search; + export default Search; +} + +declare module 'virtual:starlight/components/SocialIcons' { + const SocialIcons: typeof import('@astrojs/starlight/components').SocialIcons; + export default SocialIcons; +} + +declare module 'virtual:starlight/components/ThemeSelect' { + const ThemeSelect: typeof import('@astrojs/starlight/components').ThemeSelect; + export default ThemeSelect; +} diff --git a/docs/gonx-docs/src/lib/code-blocks.ts b/docs/gonx-docs/src/lib/code-blocks.ts new file mode 100644 index 000000000..98c09a31e --- /dev/null +++ b/docs/gonx-docs/src/lib/code-blocks.ts @@ -0,0 +1,55 @@ +const COPY_ICON = ``; +const CHECK_ICON = ``; +const ERROR_ICON = ``; + +/** Enhance all `.astro-code` blocks with copy buttons and optional title bars. Idempotent. */ +export function enhanceCodeBlocks(root: ParentNode = document): void { + root.querySelectorAll('.astro-code').forEach((block) => { + if (block.parentElement?.classList.contains('code-block')) return; + + const wrapper = document.createElement('div'); + wrapper.className = 'code-block'; + + const title = block.getAttribute('data-title') || ''; + if (title) { + const header = document.createElement('div'); + header.className = 'code-block-header'; + const titleSpan = document.createElement('span'); + titleSpan.className = 'code-block-title'; + titleSpan.textContent = title; + header.appendChild(titleSpan); + wrapper.appendChild(header); + } + + const copyBtn = document.createElement('button'); + copyBtn.className = 'code-copy-btn'; + copyBtn.type = 'button'; + copyBtn.setAttribute('aria-label', 'Copy to clipboard'); + copyBtn.innerHTML = COPY_ICON; + copyBtn.addEventListener('click', async () => { + const code = + block.querySelector('code')?.textContent || block.textContent || ''; + try { + await navigator.clipboard.writeText(code); + copyBtn.innerHTML = CHECK_ICON; + setTimeout(() => { + copyBtn.innerHTML = COPY_ICON; + }, 2000); + } catch { + copyBtn.innerHTML = ERROR_ICON; + copyBtn.setAttribute( + 'aria-label', + 'Copy failed — try selecting text manually' + ); + setTimeout(() => { + copyBtn.innerHTML = COPY_ICON; + copyBtn.setAttribute('aria-label', 'Copy to clipboard'); + }, 2000); + } + }); + + block.parentNode!.insertBefore(wrapper, block); + wrapper.appendChild(block); + wrapper.appendChild(copyBtn); + }); +} diff --git a/docs/gonx-docs/src/lib/copy-for-ai.ts b/docs/gonx-docs/src/lib/copy-for-ai.ts new file mode 100644 index 000000000..e87111bb6 --- /dev/null +++ b/docs/gonx-docs/src/lib/copy-for-ai.ts @@ -0,0 +1,61 @@ +/** Convert a DOM element's content to a markdown string. */ +export function domToMarkdown(root: Element): string { + const lines: string[] = []; + + root + .querySelectorAll('h1, h2, h3, h4, h5, h6, p, li, pre code, blockquote') + .forEach((el) => { + const tag = el.tagName.toLowerCase(); + if (tag === 'code' && el.parentElement?.tagName === 'PRE') { + const lang = el.className?.match(/language-(\w+)/)?.[1] || ''; + lines.push('```' + lang, el.textContent?.trim() || '', '```', ''); + } else if (tag.startsWith('h')) { + const level = '#'.repeat(parseInt(tag[1])); + lines.push(`${level} ${el.textContent?.trim()}`, ''); + } else if (tag === 'li') { + lines.push(`- ${el.textContent?.trim()}`); + } else if (tag === 'blockquote') { + lines.push(`> ${el.textContent?.trim()}`, ''); + } else { + lines.push(el.textContent?.trim() || '', ''); + } + }); + + return lines.join('\n').replace(/\n{3,}/g, '\n\n'); +} + +const BOUND_ATTR = 'data-copy-for-ai-bound'; + +/** Attach click handlers to all `.copy-for-ai-btn` elements on the page. Idempotent. */ +export function initCopyForAi(): void { + document.querySelectorAll('.copy-for-ai-btn').forEach((btn) => { + if (btn.hasAttribute(BOUND_ATTR)) return; + btn.setAttribute(BOUND_ATTR, ''); + + let resetTimer: ReturnType | undefined; + + btn.addEventListener('click', async () => { + const content = document.querySelector('.sl-markdown-content'); + if (!content) return; + + const title = document.querySelector('h1')?.textContent?.trim() || ''; + const url = window.location.href; + + const markdown = `# ${title}\nSource: ${url}\n\n${domToMarkdown( + content + )}`; + + clearTimeout(resetTimer); + const original = btn.innerHTML; + try { + await navigator.clipboard.writeText(markdown); + btn.innerHTML = ` Copied!`; + } catch { + btn.innerHTML = ` Copy failed`; + } + resetTimer = setTimeout(() => { + btn.innerHTML = original; + }, 2000); + }); + }); +} diff --git a/docs/gonx-docs/src/lib/page-feedback.ts b/docs/gonx-docs/src/lib/page-feedback.ts new file mode 100644 index 000000000..4c6d61e20 --- /dev/null +++ b/docs/gonx-docs/src/lib/page-feedback.ts @@ -0,0 +1,45 @@ +import { safeGetItem, safeSetItem } from './preferences'; + +class PageFeedback extends HTMLElement { + #ac!: AbortController; + + connectedCallback() { + this.#ac = new AbortController(); + const { signal } = this.#ac; + const pageId = this.dataset.pageId; + const stored = safeGetItem(`feedback:${pageId}`); + + if (stored) { + const btn = [...this.querySelectorAll('.feedback-btn')].find( + (b) => b.dataset.value === stored + ); + if (btn) { + btn.setAttribute('data-selected', 'true'); + btn.setAttribute('aria-pressed', 'true'); + } + } + + this.querySelectorAll('.feedback-btn').forEach((btn) => { + btn.addEventListener( + 'click', + () => { + const value = (btn as HTMLElement).dataset.value; + this.querySelectorAll('.feedback-btn').forEach((b) => { + b.removeAttribute('data-selected'); + b.setAttribute('aria-pressed', 'false'); + }); + btn.setAttribute('data-selected', 'true'); + btn.setAttribute('aria-pressed', 'true'); + safeSetItem(`feedback:${pageId}`, value || ''); + }, + { signal } + ); + }); + } + + disconnectedCallback() { + this.#ac.abort(); + } +} + +customElements.define('page-feedback', PageFeedback); diff --git a/docs/gonx-docs/src/lib/preferences.ts b/docs/gonx-docs/src/lib/preferences.ts new file mode 100644 index 000000000..25c3bd32e --- /dev/null +++ b/docs/gonx-docs/src/lib/preferences.ts @@ -0,0 +1,17 @@ +/** Read from localStorage, returning null if storage is unavailable. */ +export function safeGetItem(key: string): string | null { + try { + return localStorage.getItem(key); + } catch { + return null; + } +} + +/** Write to localStorage, silently failing if storage is unavailable. */ +export function safeSetItem(key: string, value: string): void { + try { + localStorage.setItem(key, value); + } catch { + /* storage unavailable */ + } +} diff --git a/docs/gonx-docs/src/lib/toc-path.ts b/docs/gonx-docs/src/lib/toc-path.ts new file mode 100644 index 000000000..764439c7c --- /dev/null +++ b/docs/gonx-docs/src/lib/toc-path.ts @@ -0,0 +1,175 @@ +export interface Point { + x: number; + y: number; +} + +/** Build an SVG path string with cubic bezier curves connecting points. */ +export function buildSerpentinePath(points: Point[]): string { + if (points.length === 0) return ''; + let d = `M ${points[0].x},${points[0].y}`; + for (let i = 1; i < points.length; i++) { + const prev = points[i - 1]; + const curr = points[i]; + const midY = (prev.y + curr.y) / 2; + d += ` C ${prev.x},${midY} ${curr.x},${midY} ${curr.x},${curr.y}`; + } + return d; +} + +/** + * Given heading positions (as getBoundingClientRect().top values) and scroll + * metrics, return the index of the active heading. + * + * Near the bottom of the page, the activation offset smoothly expands from + * baseOffset to viewportHeight/2 so headings that can't physically reach the + * base offset still get their turn. + */ +export function resolveActiveIndex( + headingTops: number[], + scrollY: number, + scrollHeight: number, + viewportHeight: number, + baseOffset = 100, + nearBottomRatio = 0.6 +): number { + if (headingTops.length === 0) return 0; + + const maxScroll = scrollHeight - viewportHeight; + const distToBottom = Math.max(0, maxScroll - scrollY); + const nearBottomZone = viewportHeight * nearBottomRatio; + + const offset = + distToBottom < nearBottomZone + ? baseOffset + + (1 - distToBottom / nearBottomZone) * (viewportHeight / 2 - baseOffset) + : baseOffset; + + let active = 0; + for (let i = 0; i < headingTops.length; i++) { + if (headingTops[i] <= offset) active = i; + } + return active; +} + +// ── DOM orchestration ───────────────────────────────────────────── + +let cleanup: (() => void) | null = null; + +/** Initialize the ToC SVG serpentine indicator and scroll tracking. */ +export function initTocPath(): void { + cleanup?.(); + cleanup = null; + + const toc = document.querySelector('starlight-toc nav > ul'); + if (!toc) return; + + const links = [...toc.querySelectorAll('a')]; + if (links.length < 2) return; + + if (toc.parentElement?.classList.contains('toc-items-wrapper')) return; + + const wrapper = document.createElement('div'); + wrapper.className = 'toc-items-wrapper'; + toc.parentNode!.insertBefore(wrapper, toc); + wrapper.appendChild(toc); + + const ns = 'http://www.w3.org/2000/svg'; + const svg = document.createElementNS(ns, 'svg'); + svg.classList.add('toc-path-svg'); + svg.setAttribute('aria-hidden', 'true'); + + const bgPath = document.createElementNS(ns, 'path'); + bgPath.classList.add('toc-path-bg'); + const activePath = document.createElementNS(ns, 'path'); + activePath.classList.add('toc-path-active'); + svg.append(bgPath, activePath); + wrapper.prepend(svg); + + let points: Point[] = []; + + function buildPath() { + const wRect = wrapper.getBoundingClientRect(); + + points = links.map((link) => { + const rect = link.getBoundingClientRect(); + return { + x: Math.max(2, rect.left - wRect.left - 8), + y: rect.top - wRect.top + rect.height / 2, + }; + }); + + const svgW = Math.max(16, ...points.map((p) => p.x + 4)); + const svgH = wRect.height; + svg.setAttribute('width', String(svgW)); + svg.setAttribute('height', String(svgH)); + svg.setAttribute('viewBox', `0 0 ${svgW} ${svgH}`); + + const d = buildSerpentinePath(points); + bgPath.setAttribute('d', d); + activePath.setAttribute('d', d); + } + + buildPath(); + + function getActiveLink(): HTMLAnchorElement { + const headingTops = links.map((link) => { + const id = decodeURIComponent(link.hash.slice(1)); + const el = document.getElementById(id); + return el ? el.getBoundingClientRect().top : Infinity; + }); + + const idx = resolveActiveIndex( + headingTops, + window.scrollY, + document.documentElement.scrollHeight, + window.innerHeight + ); + return links[idx]; + } + + function update() { + const activeLink = getActiveLink(); + + links.forEach((l) => l.classList.remove('toc-active')); + activeLink.classList.add('toc-active'); + + const idx = links.indexOf(activeLink); + if (idx >= 0 && points[idx]) { + const clipY = points[idx].y + 4; + activePath.style.clipPath = `polygon(0 0, 100% 0, 100% ${clipY}px, 0 ${clipY}px)`; + } + } + + update(); + + const ro = new ResizeObserver(() => { + buildPath(); + update(); + }); + ro.observe(wrapper); + + // Use window.AbortController so the signal is owned by the same Window + // object that owns the event target — required for jsdom compatibility. + const ac = new window.AbortController(); + let scrollTimer: ReturnType | undefined; + window.addEventListener( + 'scroll', + () => { + clearTimeout(scrollTimer); + scrollTimer = setTimeout(update, 30); + }, + { passive: true, signal: ac.signal } + ); + + cleanup = () => { + clearTimeout(scrollTimer); + ac.abort(); + ro.disconnect(); + }; +} + +/** Tear down scroll listener and ResizeObserver. Safe to call when not initialized. */ +export function cleanupTocPath(): void { + cleanup?.(); + cleanup = null; +} diff --git a/docs/gonx-docs/src/pages/404.astro b/docs/gonx-docs/src/pages/404.astro index ea0b2bf40..91a448195 100644 --- a/docs/gonx-docs/src/pages/404.astro +++ b/docs/gonx-docs/src/pages/404.astro @@ -20,9 +20,9 @@ import { Icon } from '@astrojs/starlight/components'; - +

Oops! Page Not Found

- +

Here's what you can do:

@@ -32,14 +32,14 @@ import { Icon } from '@astrojs/starlight/components';

Start fresh from our homepage

Take me home
- +

Browse Docs

Explore GoNx documentation

- View docs + View docs
- +

Report Issue

@@ -47,7 +47,7 @@ import { Icon } from '@astrojs/starlight/components'; Report bug
- + @@ -75,12 +75,11 @@ import { Icon } from '@astrojs/starlight/components'; .error-code { font-size: clamp(4rem, 12vw, 8rem); font-weight: 900; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient(135deg, var(--color-accent-500) 0%, var(--color-accent-700) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; margin-bottom: 1rem; - text-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); animation: pulse 2s ease-in-out infinite alternate; } @@ -134,16 +133,6 @@ import { Icon } from '@astrojs/starlight/components'; font-weight: 700; } - .error-description { - font-size: 1.2rem; - color: var(--sl-color-text-accent); - margin-bottom: 3rem; - line-height: 1.6; - max-width: 600px; - margin-left: auto; - margin-right: auto; - } - .suggestions { margin-bottom: 3rem; } @@ -161,16 +150,31 @@ import { Icon } from '@astrojs/starlight/components'; margin-bottom: 2rem; } - .suggestion-item { + :root[data-theme='dark'] .suggestion-item { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); + } + + :root[data-theme='light'] .suggestion-item { + background: rgba(30, 27, 46, 0.03); + border: 1px solid rgba(30, 27, 46, 0.08); + } + + .suggestion-item { border-radius: 12px; padding: 1.5rem; transition: all 0.3s ease; } - .suggestion-item:hover { + :root[data-theme='dark'] .suggestion-item:hover { background: rgba(255, 255, 255, 0.08); + } + + :root[data-theme='light'] .suggestion-item:hover { + background: rgba(30, 27, 46, 0.06); + } + + .suggestion-item:hover { transform: translateY(-4px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); } @@ -189,7 +193,7 @@ import { Icon } from '@astrojs/starlight/components'; .suggestion-link { display: inline-block; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient(135deg, var(--color-accent-500) 0%, var(--color-accent-700) 100%); color: white; padding: 0.5rem 1rem; border-radius: 6px; @@ -201,57 +205,28 @@ import { Icon } from '@astrojs/starlight/components'; .suggestion-link:hover { transform: translateY(-2px); - box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4); + box-shadow: 0 4px 12px color-mix(in srgb, var(--color-accent-500) 40%, transparent); text-decoration: none; } - .popular-pages h2 { - font-size: 1.3rem; - margin-bottom: 1.5rem; - color: var(--sl-color-text); - } - - .popular-links { - display: flex; - flex-wrap: wrap; - gap: 1rem; - justify-content: center; - } - - .popular-link { - display: flex; - align-items: center; - gap: 0.5rem; - background: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.1); - padding: 0.75rem 1rem; - border-radius: 8px; - text-decoration: none; - color: var(--sl-color-text-accent); - transition: all 0.3s ease; - font-size: 0.9rem; - } - - .popular-link:hover { - background: rgba(255, 255, 255, 0.08); - color: var(--sl-color-text); - text-decoration: none; - transform: translateY(-2px); - } - @media (max-width: 600px) { .suggestion-grid { grid-template-columns: 1fr; } - - .popular-links { - flex-direction: column; - align-items: center; - } - + .floating-element { font-size: 1.5rem; } } + + @media (prefers-reduced-motion: reduce) { + .error-code, + .floating-element, + .suggestion-item, + .suggestion-link { + animation-duration: 0s !important; + transition-duration: 0s !important; + } + } diff --git a/docs/gonx-docs/src/styles/code-blocks.css b/docs/gonx-docs/src/styles/code-blocks.css new file mode 100644 index 000000000..3492d28cc --- /dev/null +++ b/docs/gonx-docs/src/styles/code-blocks.css @@ -0,0 +1,133 @@ +/* ── Code blocks: Shiki with glass treatment ───────────────────── */ + +/* Wrapper added by JS (code-blocks.ts) */ +.code-block { + position: relative; + margin: 1rem 0; +} + +/* Title bar (file tab) */ +.code-block-header { + display: flex; + align-items: center; + padding: 0.5rem 1rem; + font-family: var(--font-code, 'JetBrains Mono'), monospace; + font-size: 0.75rem; + font-weight: 500; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.5rem 0.5rem 0 0; +} + +:root[data-theme='dark'] .code-block-header { + background: rgba(20, 17, 40, 0.5); + color: #8a8aad; +} + +:root[data-theme='light'] .code-block-header { + background: rgba(238, 235, 248, 0.6); + color: #6a6a8a; + border-bottom-color: rgba(30, 27, 46, 0.08); +} + +.code-block-header + .astro-code { + border-top-left-radius: 0; + border-top-right-radius: 0; + margin-top: 0; +} + +/* Copy button */ +.code-copy-btn { + position: absolute; + top: 0.5rem; + right: 0.5rem; + display: flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + padding: 0; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 0.375rem; + background: rgba(255, 255, 255, 0.05); + color: var(--sl-color-gray-3); + cursor: pointer; + opacity: 0; + pointer-events: none; + transition: opacity 0.15s, color 0.15s, background 0.15s; +} + +.code-block:hover .code-copy-btn, +.code-block:focus-within .code-copy-btn, +.code-copy-btn:focus-visible { + opacity: 1; + pointer-events: auto; +} + +@media (hover: none), (pointer: coarse) { + .code-copy-btn { + opacity: 1; + pointer-events: auto; + } +} + +.code-copy-btn:hover { + color: var(--color-accent-500); + background: color-mix(in srgb, var(--color-accent-500) 10%, transparent); + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); +} + +/* If there's a header, push copy button below it */ +.code-block-header ~ .code-copy-btn { + top: calc(0.5rem + 2rem + 1px); +} + +:root[data-theme='light'] .code-copy-btn { + border-color: rgba(30, 27, 46, 0.1); + background: rgba(255, 255, 255, 0.6); +} + +:root[data-theme='light'] .code-copy-btn:hover { + color: var(--color-accent-500); + background: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); +} + +/* Base code block styling */ +.astro-code { + padding: 1rem 1.25rem; + border-radius: 0.5rem; + font-family: var(--font-code, 'JetBrains Mono'), monospace; + font-size: 0.875rem; + line-height: 1.7; + overflow-x: auto; + tab-size: 2; + margin: 0; +} + +/* Shiki inlines styles on elements — !important is the only + way to override inline styles and apply our glass treatment. */ +:root[data-theme='dark'] .astro-code, +:root[data-theme='dark'] .astro-code span { + color: var(--shiki-dark) !important; + background-color: transparent !important; +} + +:root[data-theme='dark'] .astro-code { + background: rgba(20, 17, 40, 0.4) !important; + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 4px 24px rgba(0, 0, 0, 0.25); +} + +:root[data-theme='light'] .astro-code, +:root[data-theme='light'] .astro-code span { + color: var(--shiki-light) !important; + background-color: transparent !important; +} + +:root[data-theme='light'] .astro-code { + background: rgba(238, 235, 248, 0.5) !important; + border: 1px solid rgba(30, 27, 46, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), + 0 4px 24px rgba(0, 0, 0, 0.06); +} diff --git a/docs/gonx-docs/src/styles/components.css b/docs/gonx-docs/src/styles/components.css new file mode 100644 index 000000000..36945a55b --- /dev/null +++ b/docs/gonx-docs/src/styles/components.css @@ -0,0 +1,235 @@ +/* ── Content components: inline code, cards, links, asides ──────── */ + +/* Inline code pills */ +.sl-markdown-content :not(pre) > code { + padding: 0.1em 0.4em; + border-radius: 0.3rem; + font-size: 0.875em; +} + +:root[data-theme='dark'] .sl-markdown-content :not(pre) > code { + background: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border: 1px solid color-mix(in srgb, var(--color-accent-500) 12%, transparent); + /* Bespoke light tint (brighter than accent-500) for legibility on the dark bg */ + color: #a5b4fc; +} + +:root[data-theme='light'] .sl-markdown-content :not(pre) > code { + background: color-mix(in srgb, var(--color-accent-500) 6%, transparent); + border: 1px solid color-mix(in srgb, var(--color-accent-500) 10%, transparent); + /* Darker brand shade: accent-500 fails AA contrast on the light bg */ + color: var(--color-accent-700); +} + +/* Glass cards (Starlight Card components) — unlayered CSS overrides + Starlight's layered defaults per cascade layer best practices. */ +:root[data-theme='dark'] .card { + background: rgba(30, 27, 46, 0.6); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.75rem; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 4px 24px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(8px); + transition: border-color 0.2s, box-shadow 0.2s; +} + +:root[data-theme='dark'] .card:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 15%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 4px 24px rgba(0, 0, 0, 0.2), + 0 0 20px color-mix(in srgb, var(--color-accent-500) 6%, transparent); +} + +:root[data-theme='light'] .card { + background: rgba(255, 255, 255, 0.6); + border: 1px solid rgba(30, 27, 46, 0.08); + border-radius: 0.75rem; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), + 0 4px 24px rgba(0, 0, 0, 0.06); + transition: border-color 0.2s, box-shadow 0.2s; +} + +:root[data-theme='light'] .card:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 15%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), + 0 4px 24px rgba(0, 0, 0, 0.06), + 0 0 20px color-mix(in srgb, var(--color-accent-500) 6%, transparent); +} + +/* Link glow on hover */ +.sl-markdown-content a:not([class]) { + transition: color 0.15s, text-shadow 0.15s; +} + +:root[data-theme='dark'] .sl-markdown-content a:not([class]):hover { + text-shadow: 0 0 12px + color-mix(in srgb, var(--color-accent-500) 30%, transparent); +} + +:root[data-theme='light'] .sl-markdown-content a:not([class]):hover { + text-shadow: 0 0 12px + color-mix(in srgb, var(--color-accent-500) 15%, transparent); +} + +/* Asides/Callouts: glass-card treatment */ +:root[data-theme='dark'] .starlight-aside { + background: rgba(30, 27, 46, 0.6); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.75rem; + border-inline-start-width: 3px; +} + +:root[data-theme='light'] .starlight-aside { + background: rgba(30, 27, 46, 0.03); + border: 1px solid rgba(30, 27, 46, 0.08); + border-radius: 0.75rem; + border-inline-start-width: 3px; +} + +/* ── Search dialog ───────────────────────────────────────────────── */ + +site-search dialog { + opacity: 0; + transform: scale(0.95) translateY(-12px); + transition: opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1), + transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), + display 0.25s ease-out allow-discrete; +} + +site-search dialog[open] { + opacity: 1; + transform: scale(1) translateY(0); +} + +@starting-style { + site-search dialog[open] { + opacity: 0; + transform: scale(0.95) translateY(-12px); + } +} + +:root[data-theme='dark'] site-search dialog { + background: rgba(20, 17, 40, 0.85); + backdrop-filter: blur(20px) saturate(1.2); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 0.75rem; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6), 0 0 1px rgba(255, 255, 255, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.04); +} + +:root[data-theme='light'] site-search dialog { + background: rgba(250, 249, 253, 0.9); + backdrop-filter: blur(20px) saturate(1.2); + border: 1px solid rgba(30, 27, 46, 0.1); + border-radius: 0.75rem; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.12), 0 0 1px rgba(30, 27, 46, 0.08); +} + +site-search dialog::backdrop { + background-color: rgba(5, 8, 16, 0); + transition: background-color 0.25s ease-out, + display 0.25s ease-out allow-discrete; +} + +site-search dialog[open]::backdrop { + background-color: rgba(5, 8, 16, 0.75); +} + +@starting-style { + site-search dialog[open]::backdrop { + background-color: rgba(5, 8, 16, 0); + } +} + +:root[data-theme='light'] site-search dialog[open]::backdrop { + background-color: rgba(30, 27, 46, 0.3); +} + +.sidebar-search button[data-open-modal] kbd { + display: inline-flex; + font-family: var(--font-mono); + font-size: 0.65rem; + padding: 0.1em 0.4em; + border-radius: 0.25rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.05); + margin-inline-start: auto; +} + +/* ── Feedback buttons ────────────────────────────────────────────── */ + +.feedback-btn { + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.35rem 0.75rem; + border-radius: 0.5rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.03); + color: var(--sl-color-gray-2); + cursor: pointer; + font-size: 0.8rem; + transition: border-color 0.15s, background-color 0.15s, color 0.15s; +} + +.feedback-btn:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 6%, transparent); + color: var(--color-accent-500); +} + +.feedback-btn[data-selected='true'] { + border-color: color-mix(in srgb, var(--color-accent-500) 30%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 10%, transparent); + color: var(--color-accent-500); +} + +:root[data-theme='light'] .feedback-btn { + border-color: rgba(30, 27, 46, 0.12); + background: rgba(30, 27, 46, 0.03); +} + +:root[data-theme='light'] .feedback-btn:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 6%, transparent); + color: var(--color-accent-500); +} + +:root[data-theme='light'] .feedback-btn[data-selected='true'] { + border-color: color-mix(in srgb, var(--color-accent-500) 30%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + color: var(--color-accent-500); +} + +/* ── Focus indicators (keyboard accessibility) ──────────────────── */ + +:focus-visible { + outline: 2px solid var(--color-accent-500); + outline-offset: 2px; + border-radius: 0.25rem; +} + +:root[data-theme='light'] :focus-visible { + outline-color: var(--color-accent-500); +} + +/* ── Reduced motion ─────────────────────────────────────────────── */ + +@media (prefers-reduced-motion: reduce) { + nav.sidebar details > ul, + nav.sidebar details > summary svg, + site-search dialog, + site-search dialog::backdrop, + .toc-path-active, + .code-copy-btn, + .feedback-btn, + starlight-toc a { + transition-duration: 0s !important; + animation-duration: 0s !important; + } + + ::view-transition-old(main-content), + ::view-transition-new(main-content) { + animation-duration: 0s !important; + } +} diff --git a/docs/gonx-docs/src/styles/custom.css b/docs/gonx-docs/src/styles/custom.css index 233475a12..6f23ecaf0 100644 --- a/docs/gonx-docs/src/styles/custom.css +++ b/docs/gonx-docs/src/styles/custom.css @@ -1,3 +1,132 @@ +@layer base, starlight, theme, components, utilities; + +@import '@astrojs/starlight-tailwind'; +@import 'tailwindcss/theme.css' layer(theme); +@import 'tailwindcss/utilities.css' layer(utilities); + +@import './theme-vars.css'; +@import './code-blocks.css'; +@import './sidebar.css'; +@import './layout.css'; +@import './toc.css'; +@import './components.css'; + +@theme { + /* ── Breakpoint: matches Starlight's mobile/desktop split ────────── */ + --breakpoint-desktop: 50rem; + + /* ── Typography (matching apps/www) ──────────────────────────────── */ + /* Body shares the heading face (Inter); aliased here so Astro registers Inter once */ + --font-body: var(--font-heading); + --font-sans: var(--font-body, 'Inter'), 'SF Pro Display', -apple-system, + BlinkMacSystemFont, system-ui, sans-serif; + --font-mono: var(--font-code, 'JetBrains Mono'), 'SF Mono', 'Geist Mono', + ui-monospace, Menlo, monospace; + --font-display: var(--font-heading, 'Inter'), 'SF Pro Display', -apple-system, + system-ui, sans-serif; + + /* ── Accent: Brand purple ─────────────────────────────────────────── */ + --color-accent-50: #eef2ff; + --color-accent-100: #e0e7ff; + --color-accent-200: #c7d2fe; + --color-accent-300: #a5b4fc; + --color-accent-400: #818cf8; + --color-accent-500: #667eea; + --color-accent-600: #5a67d8; + --color-accent-700: #4f46e5; + --color-accent-800: #4338ca; + --color-accent-900: #3730a3; + --color-accent-950: #1e1b4b; + + /* ── Gray: Ocean-tinted navy scale (anchored to www text hierarchy) */ + --color-gray-50: #e7ecf3; + --color-gray-100: #c4d4e4; + --color-gray-200: #a8bbd0; + --color-gray-300: #9aa3b2; + --color-gray-400: #7a8a9c; + --color-gray-500: #5e6675; + --color-gray-600: #1a3a55; + --color-gray-700: #0f2b4a; + --color-gray-800: #0b0e16; + --color-gray-900: #07090f; + --color-gray-950: #04060b; + + /* ── Border radius tokens (matching www) ───────────────────────── */ + --r-sm: 8px; + --r-md: 12px; + --r-lg: 18px; + --r-xl: 28px; +} + +/* ── Base content styling ──────────────────────────────────────────── */ + +/* Headings use Inter (matching www) */ +.sl-markdown-content :is(h1, h2, h3, h4, h5, h6), +starlight-toc h2 { + font-family: var(--font-display); +} + +/* Content width and spacing */ +:root { + --sl-content-width: 52rem; + --sl-content-pad-x: 2rem; +} + +/* Thin scrollbar on content area */ +html { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-idle) transparent; + font-feature-settings: 'ss01', 'ss02', 'cv11'; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; +} + +html:hover { + scrollbar-color: var(--scrollbar-hover) transparent; +} + +/* ── Noise texture overlay (matching www) ───────────────────────── */ +.main-frame::before { + content: ''; + position: fixed; + inset: 0; + z-index: 100; + pointer-events: none; + opacity: 0.035; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); + background-repeat: repeat; + background-size: 256px; +} + +:root[data-theme='light'] .main-frame::before { + opacity: 0.02; +} + +/* h2 gradient bottom border */ +.sl-markdown-content h2 { + border-bottom: 1px solid transparent; + border-image: linear-gradient( + 90deg, + color-mix(in srgb, var(--color-accent-500) 30%, transparent), + rgba(102, 126, 234, 0.15), + transparent + ) + 1; + padding-bottom: 0.5rem; +} + +:root[data-theme='light'] .sl-markdown-content h2 { + border-image: linear-gradient( + 90deg, + color-mix(in srgb, var(--color-accent-500) 20%, transparent), + rgba(102, 126, 234, 0.08), + transparent + ) + 1; +} + +/* ── Landing page components ───────────────────────────────────────── */ + .features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); @@ -5,17 +134,32 @@ margin: 3rem 0; } -.feature-item { +:root[data-theme='dark'] .feature-item { background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); +} + +:root[data-theme='light'] .feature-item { + background: rgba(30, 27, 46, 0.03); + border: 1px solid rgba(30, 27, 46, 0.08); +} + +.feature-item { border-radius: 12px; padding: 1.5rem; transition: all 0.3s ease; text-align: center; } -.feature-item:hover { +:root[data-theme='dark'] .feature-item:hover { background: rgba(255, 255, 255, 0.08); +} + +:root[data-theme='light'] .feature-item:hover { + background: rgba(30, 27, 46, 0.06); +} + +.feature-item:hover { transform: translateY(-4px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); } @@ -44,64 +188,44 @@ font-size: 0.95rem; } -.stats-container { +:root[data-theme='dark'] .stats-container { background: linear-gradient( 135deg, - rgba(103, 126, 234, 0.1) 0%, + rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100% ); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +:root[data-theme='light'] .stats-container { + background: linear-gradient( + 135deg, + rgba(102, 126, 234, 0.08) 0%, + rgba(118, 75, 162, 0.08) 100% + ); + border: 1px solid rgba(30, 27, 46, 0.08); +} + +.stats-container { border-radius: 16px; padding: 3rem; margin: 4rem 0; text-align: center; - border: 1px solid rgba(255, 255, 255, 0.1); } .stats-container h2 { margin-bottom: 1rem; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient( + 135deg, + var(--color-accent-500) 0%, + var(--color-accent-700) 100% + ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-weight: 700; } -.stats-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); - gap: 2rem; - margin-top: 2rem; -} - -.stat-item { - padding: 1rem; - transition: transform 0.3s ease; -} - -.stat-item:hover { - transform: translateY(-4px); -} - -.stat-number { - font-size: 2.5rem; - font-weight: 700; - color: var(--sl-color-text); - display: block; - margin-bottom: 0.5rem; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.stat-label { - color: var(--sl-color-text-accent); - font-size: 0.9rem; - text-transform: uppercase; - letter-spacing: 0.5px; - font-weight: 600; -} - .action-buttons { display: flex; gap: 1rem; @@ -126,26 +250,40 @@ } .action-button.primary { - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient( + 135deg, + var(--color-accent-500) 0%, + var(--color-accent-700) 100% + ); color: white; } -.action-button.secondary { +:root[data-theme='dark'] .action-button.secondary { background: rgba(255, 255, 255, 0.1); color: var(--sl-color-text); border: 1px solid rgba(255, 255, 255, 0.2); } +:root[data-theme='light'] .action-button.secondary { + background: rgba(30, 27, 46, 0.05); + color: var(--sl-color-text); + border: 1px solid rgba(30, 27, 46, 0.12); +} + .action-button:hover { transform: translateY(-2px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); } .action-button.primary:hover { - background: linear-gradient(135deg, #5a67d8 0%, #6b46c1 100%); + background: linear-gradient( + 135deg, + var(--color-accent-600) 0%, + var(--color-accent-800) 100% + ); } -@media (max-width: 768px) { +@media (max-width: 49.9999rem) { .stats-container { padding: 2rem; } @@ -172,18 +310,3 @@ font-size: 2rem; } } - -@media (prefers-color-scheme: dark) { - .feature-item { - background: rgba(255, 255, 255, 0.03); - border-color: rgba(255, 255, 255, 0.08); - } - - .feature-item:hover { - background: rgba(255, 255, 255, 0.06); - } - - .stats-container { - border-color: rgba(255, 255, 255, 0.08); - } -} diff --git a/docs/gonx-docs/src/styles/layout.css b/docs/gonx-docs/src/styles/layout.css new file mode 100644 index 000000000..c6dfe4fda --- /dev/null +++ b/docs/gonx-docs/src/styles/layout.css @@ -0,0 +1,68 @@ +/* ── Layout: desktop/mobile header & view transitions ────────────── */ + +/* Hide header on desktop (Fumadocs pattern) */ +@media (min-width: 50rem) { + :root { + --sl-nav-height: 0rem; + } + + .page > .header { + display: none; + } + + .sidebar-pane { + inset-block-start: 0; + } + + .main-frame { + padding-top: 0; + } +} + +/* Thin mobile header */ +@media (max-width: 49.9999rem) { + :root { + --sl-nav-height: 2.5rem; + } + + .page > .header { + background-color: var(--sl-color-bg-nav); + border-bottom: 1px solid + var(--sl-color-hairline-shade, rgba(255, 255, 255, 0.06)); + } + + :root[data-theme='light'] .page > .header { + background-color: #f3f2f8; + border-bottom: 1px solid rgba(30, 27, 46, 0.08); + } +} + +/* Mobile ToC bar */ +:root[data-theme='dark'] starlight-toc mobile-starlight-toc { + background-color: #07090f; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +/* Content area background — descending gradient */ +:root[data-theme='dark'] .main-frame { + background: linear-gradient(180deg, #0b0e16 0%, #04060b 40%); +} + +/* ── View Transitions ────────────────────────────────────────────── */ +/* Prevent sidebar flash during client-side navigation by isolating + main content and sidebar into their own transition groups. */ + +.main-frame { + view-transition-name: main-content; +} + +.sidebar-pane { + view-transition-name: sidebar; +} + +::view-transition-old(main-content), +::view-transition-new(main-content), +::view-transition-old(sidebar), +::view-transition-new(sidebar) { + animation-duration: 0s; +} diff --git a/docs/gonx-docs/src/styles/sidebar.css b/docs/gonx-docs/src/styles/sidebar.css new file mode 100644 index 000000000..0bf056fb1 --- /dev/null +++ b/docs/gonx-docs/src/styles/sidebar.css @@ -0,0 +1,139 @@ +/* ── Sidebar: contrast, active states & layout ─────────────────── */ + +/* Section group headers — kicker style */ +nav.sidebar .top-level > li > details > summary, +nav.sidebar .top-level > li > a.large { + font-family: var(--font-mono); + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.1em; +} + +:root[data-theme='dark'] nav.sidebar .top-level > li > details > summary, +:root[data-theme='dark'] nav.sidebar .top-level > li > a.large { + color: #e8e6ff; +} + +:root[data-theme='light'] nav.sidebar .top-level > li > details > summary, +:root[data-theme='light'] nav.sidebar .top-level > li > a.large { + color: #1e1b2e; +} + +/* Sidebar links — dark mode */ +:root[data-theme='dark'] nav.sidebar a:not(.sidebar-logo) { + color: #8a8aad; + transition: color 0.15s, background-color 0.15s; +} + +:root[data-theme='dark'] nav.sidebar a:not(.sidebar-logo):hover { + color: #c4c6e0; + background-color: color-mix(in srgb, var(--color-accent-500) 4%, transparent); +} + +:root[data-theme='dark'] nav.sidebar a[aria-current='page'] { + color: #e8e6ff; + background-color: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border-inline-start: 2px solid var(--color-accent-500); + font-weight: 500; +} + +/* Sidebar links — light mode */ +:root[data-theme='light'] nav.sidebar a:not(.sidebar-logo) { + color: #555580; +} + +:root[data-theme='light'] nav.sidebar a:not(.sidebar-logo):hover { + color: #1e1b2e; + background-color: color-mix(in srgb, var(--color-accent-500) 4%, transparent); +} + +:root[data-theme='light'] nav.sidebar a[aria-current='page'] { + color: #1e1b2e; + background-color: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border-inline-start: 2px solid var(--color-accent-500); + font-weight: 500; +} + +/* Sidebar border & background */ +:root[data-theme='dark'] .sidebar-pane { + background-color: #07090f; + border-inline-end-color: rgba(255, 255, 255, 0.06); +} + +:root[data-theme='light'] .sidebar-pane { + background-color: #f3f2f8; + border-inline-end-color: rgba(30, 27, 46, 0.08); +} + +/* ── Sidebar layout: fixed top/bottom, scrollable nav ──────────── + These override Starlight's default sidebar layout to support a + fixed chrome area at top and bottom with a scrollable nav in + between. The !important declarations are necessary because + Starlight applies inline-level specificity on these elements. */ + +.sidebar-content { + display: flex !important; + flex-direction: column !important; + height: 100% !important; + min-height: 0 !important; +} + +.sidebar-content sl-sidebar-state-persist { + display: block !important; + flex: 1 1 0% !important; + min-height: 0 !important; + overflow-y: auto !important; +} + +.sidebar-bottom { + flex-shrink: 0; +} + +@media (min-width: 50rem) { + .sidebar-pane { + overflow: hidden !important; + } + + .sidebar-content { + overflow: hidden !important; + } + + .sidebar-content sl-sidebar-state-persist { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-idle) transparent; + } + + .sidebar-content sl-sidebar-state-persist:hover { + scrollbar-color: var(--scrollbar-hover) transparent; + } + + .sidebar-chrome { + flex-shrink: 0; + } +} + +/* ── Sidebar animations ──────────────────────────────────────────── */ + +nav.sidebar details > ul { + overflow: hidden; + transition: max-height 0.25s ease-out, opacity 0.2s ease-out; +} + +nav.sidebar details:not([open]) > ul { + max-height: 0; + opacity: 0; +} + +nav.sidebar details[open] > ul { + max-height: 100vh; + opacity: 1; +} + +nav.sidebar details > summary svg { + transition: transform 0.2s ease-out; +} + +nav.sidebar details[open] > summary svg { + transform: rotate(90deg); +} diff --git a/docs/gonx-docs/src/styles/theme-vars.css b/docs/gonx-docs/src/styles/theme-vars.css new file mode 100644 index 000000000..3da1c577a --- /dev/null +++ b/docs/gonx-docs/src/styles/theme-vars.css @@ -0,0 +1,49 @@ +/* ── Theme custom properties ─────────────────────────────────────── */ +/* Dark/light Starlight overrides + pagefind + scrollbar colors */ + +:root[data-theme='dark'] { + --sl-color-bg: #04060b; + --sl-color-text-accent: var(--color-accent-500); + --sl-color-bg-sidebar: #07090f; + --sl-color-backdrop-overlay: rgba(4, 6, 11, 0.8); + --sl-color-bg-nav: #07090f; + --pagefind-ui-primary: var(--color-accent-500); + --pagefind-ui-text: #e8e6ff; + --pagefind-ui-background: #0b0e16; + --pagefind-ui-border: rgba(255, 255, 255, 0.1); + --pagefind-ui-tag: color-mix( + in srgb, + var(--color-accent-500) 10%, + transparent + ); + --scrollbar-idle: rgba(255, 255, 255, 0.08); + --scrollbar-hover: rgba(255, 255, 255, 0.15); +} + +:root[data-theme='light'] { + --sl-color-bg: #faf9fd; + --sl-color-text-accent: var(--color-accent-500); + --sl-color-bg-sidebar: #f3f2f8; + --sl-color-bg-nav: #f3f2f8; + --sl-color-hairline-shade: rgba(30, 27, 46, 0.08); + --sl-color-white: #1e1b2e; + --sl-color-black: #faf9fd; + --sl-color-text: #2d2a4a; + --sl-color-gray-1: #2d2a4a; + --sl-color-gray-2: #3d3a5e; + --sl-color-gray-3: #5d5a7e; + --sl-color-gray-4: #a0a8c8; + --sl-color-gray-5: #d6d4e4; + --sl-color-gray-6: #ebe8f2; + --pagefind-ui-primary: var(--color-accent-500); + --pagefind-ui-text: #1e1b2e; + --pagefind-ui-background: #faf9fd; + --pagefind-ui-border: rgba(30, 27, 46, 0.1); + --pagefind-ui-tag: color-mix( + in srgb, + var(--color-accent-500) 8%, + transparent + ); + --scrollbar-idle: rgba(30, 27, 46, 0.08); + --scrollbar-hover: rgba(30, 27, 46, 0.15); +} diff --git a/docs/gonx-docs/src/styles/toc.css b/docs/gonx-docs/src/styles/toc.css new file mode 100644 index 000000000..7f854f16b --- /dev/null +++ b/docs/gonx-docs/src/styles/toc.css @@ -0,0 +1,67 @@ +/* ── Table of Contents: active indicator (Fumadocs-style) ──────── */ + +starlight-toc nav ul { + padding-inline-start: 1rem; +} + +starlight-toc a { + position: relative; + transition: color 0.15s; +} + +/* Neutralize Starlight's aria-current styling — our scroll-based + tracking (toc-path.ts) uses .toc-active instead. !important is + required because Starlight sets aria-current via its own + IntersectionObserver independently of our scroll tracking. */ +starlight-toc a[aria-current='true'] { + color: inherit !important; +} + +:root[data-theme='dark'] starlight-toc a.toc-active { + color: var(--color-accent-500) !important; +} + +:root[data-theme='light'] starlight-toc a.toc-active { + color: var(--color-accent-500) !important; +} + +/* Wrapper for SVG path (created by toc-path.ts) */ +.toc-items-wrapper { + position: relative; +} + +.toc-path-svg { + position: absolute; + inset-inline-start: 0; + top: 0; + pointer-events: none; +} + +.toc-path-bg { + fill: none; + stroke: rgba(255, 255, 255, 0.08); + stroke-width: 1.5; + stroke-linecap: round; +} + +.toc-path-active { + fill: none; + stroke: var(--color-accent-500); + stroke-width: 1.5; + stroke-linecap: round; + filter: drop-shadow( + 0 0 3px color-mix(in srgb, var(--color-accent-500) 40%, transparent) + ); + transition: clip-path 0.25s ease; +} + +:root[data-theme='light'] .toc-path-bg { + stroke: rgba(30, 27, 46, 0.1); +} + +:root[data-theme='light'] .toc-path-active { + stroke: var(--color-accent-500); + filter: drop-shadow( + 0 0 3px color-mix(in srgb, var(--color-accent-500) 25%, transparent) + ); +} diff --git a/docs/gonx-docs/tsconfig.json b/docs/gonx-docs/tsconfig.json index 8bf91d3bb..79ac97a6b 100644 --- a/docs/gonx-docs/tsconfig.json +++ b/docs/gonx-docs/tsconfig.json @@ -1,5 +1,14 @@ { "extends": "astro/tsconfigs/strict", - "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"] + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "react" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.astro", + "astro.config.mjs" + ], + "exclude": ["dist", "node_modules"] } diff --git a/docs/gonx-docs/wrangler.jsonc b/docs/gonx-docs/wrangler.jsonc index 16271db46..51323a27c 100644 --- a/docs/gonx-docs/wrangler.jsonc +++ b/docs/gonx-docs/wrangler.jsonc @@ -1,10 +1,19 @@ { - "$schema": "node_modules/wrangler/config-schema.json", + "$schema": "../../node_modules/wrangler/config-schema.json", "name": "gonx-docs", - // Update to today's date - "compatibility_date": "2025-03-25", + "compatibility_date": "2025-06-21", "assets": { "directory": "../../dist/docs/gonx-docs/", - "not_found_handling": "404-page" // If you have a custom `src/pages/404.astro` page + "not_found_handling": "404-page" + }, + "observability": { + "enabled": true, + "head_sampling_rate": 1, + "logs": { + "enabled": true, + "head_sampling_rate": 1, + "persist": true, + "invocation_logs": true + } } } diff --git a/docs/nx-cloudflare-docs/astro.config.mjs b/docs/nx-cloudflare-docs/astro.config.mjs new file mode 100644 index 000000000..5398621c0 --- /dev/null +++ b/docs/nx-cloudflare-docs/astro.config.mjs @@ -0,0 +1,196 @@ +import react from '@astrojs/react'; +import sitemap from '@astrojs/sitemap'; +import starlight from '@astrojs/starlight'; +import tailwindcss from '@tailwindcss/vite'; +import { defineConfig, fontProviders } from 'astro/config'; +import starlightLlmsTxt from 'starlight-llms-txt'; +import { createStarlightTypeDocPlugin } from 'starlight-typedoc'; + +const [nxCloudflareTypeDoc, nxCloudflareTypeDocSidebarGroup] = + createStarlightTypeDocPlugin(); + +// TypeDoc emits {path} relative to its `basePath` setting. We pin basePath to +// the workspace root so {path} carries the full repo-relative path (e.g. +// `packages/nx-cloudflare/src/index.ts`). +const repoRoot = '../../'; +const sourceLinkTemplate = + 'https://github.com/naxodev/oss/blob/main/{path}#L{line}'; + +export default defineConfig({ + site: 'https://nx-cloudflare.naxo.dev', + output: 'static', + outDir: '../../dist/docs/nx-cloudflare-docs', + redirects: { + '/': { destination: '/getting-started/introduction/', status: 301 }, + }, + markdown: { + shikiConfig: { + themes: { + light: 'github-light', + dark: 'github-dark', + }, + defaultColor: false, + transformers: [ + { + // Extract title="..." from code fence meta and set as data attribute + name: 'meta-title', + pre(node) { + const raw = this.options.meta?.__raw; + if (!raw) return; + const match = raw.match(/title="([^"]+)"/); + if (match) { + node.properties['data-title'] = match[1]; + } + }, + }, + ], + }, + }, + integrations: [ + starlight({ + title: 'Nx Cloudflare', + description: + 'Nx plugin for Cloudflare Workers — generators, executors, and project inference around Wrangler.', + favicon: '/favicon.svg', + disable404Route: true, + social: [ + { + icon: 'github', + label: 'GitHub', + href: 'https://github.com/naxodev/oss/tree/main/packages/nx-cloudflare', + }, + { + icon: 'npm', + label: 'npm', + href: 'https://www.npmjs.com/package/@naxodev/nx-cloudflare', + }, + { + icon: 'discord', + label: 'Discord', + href: 'https://discord.gg/zjDCGpKP2S', + }, + ], + editLink: { + baseUrl: + 'https://github.com/naxodev/oss/edit/main/docs/nx-cloudflare-docs/', + }, + plugins: [ + starlightLlmsTxt({ + projectName: 'Nx Cloudflare', + description: + 'Nx plugin for Cloudflare Workers — generators, executors, and a createNodesV2 inference plugin around Wrangler.', + details: ` +## Key Features +- **Generators**: Scaffold Cloudflare Worker applications and libraries with Wrangler config, TypeScript, and Vitest pre-configured +- **Inferred Targets**: Automatically create serve, deploy, typegen, version-upload, and tail targets from Wrangler config files +- **Project Inference**: Detect Cloudflare Worker projects via Wrangler config and build the Nx project graph + +## Package +- \`@naxodev/nx-cloudflare\` — Nx plugin for Cloudflare Workers +`, + customSets: [ + { + label: 'Getting Started', + paths: ['getting-started/**'], + description: 'Introduction, quick start, and installation', + }, + { + label: 'Guides', + paths: ['guides/**'], + description: + 'Task-oriented how-tos for generators and inferred targets', + }, + { + label: 'Reference', + paths: ['reference/**'], + description: 'API documentation for @naxodev/nx-cloudflare', + }, + ], + promote: ['getting-started/quick-start'], + }), + nxCloudflareTypeDoc({ + entryPoints: ['../../packages/nx-cloudflare/src/index.ts'], + tsconfig: '../../packages/nx-cloudflare/tsconfig.lib.json', + output: 'reference', + sidebar: { label: '@naxodev/nx-cloudflare', collapsed: true }, + typeDoc: { + excludeInternal: true, + disableGit: true, + basePath: repoRoot, + sourceLinkTemplate, + }, + }), + ], + customCss: ['./src/styles/custom.css'], + expressiveCode: false, + components: { + Header: './src/components/Header.astro', + Sidebar: './src/components/Sidebar.astro', + ThemeSelect: './src/components/ThemeSelect.astro', + Head: './src/components/Head.astro', + Pagination: './src/components/Pagination.astro', + }, + sidebar: [ + { + label: 'Getting Started', + items: [ + { slug: 'getting-started/introduction' }, + { slug: 'getting-started/quick-start' }, + { slug: 'getting-started/installation' }, + ], + }, + { + label: 'Guides', + items: [ + { slug: 'guides/generators-application' }, + { slug: 'guides/generators-init' }, + { slug: 'guides/generators-library' }, + { slug: 'guides/targets-serve' }, + { slug: 'guides/targets-deploy' }, + { slug: 'guides/targets-typegen' }, + { slug: 'guides/targets-version-upload' }, + { slug: 'guides/targets-tail' }, + ], + }, + { + label: 'Reference', + items: [nxCloudflareTypeDocSidebarGroup], + }, + { + label: 'Understanding', + items: [ + { slug: 'understanding/wrangler' }, + { slug: 'understanding/plugin-options' }, + ], + }, + { + label: 'Community', + items: [{ slug: 'community/migration' }], + }, + ], + lastUpdated: true, + pagination: true, + }), + react(), + sitemap(), + ], + vite: { + plugins: [tailwindcss()], + }, + fonts: [ + { + provider: fontProviders.google(), + name: 'Inter', + cssVariable: '--font-heading', + weights: [400, 500, 600, 700], + fallbacks: ['system-ui', 'sans-serif'], + }, + { + provider: fontProviders.google(), + name: 'JetBrains Mono', + cssVariable: '--font-code', + weights: [400, 500], + fallbacks: ['monospace'], + }, + ], +}); diff --git a/docs/nx-cloudflare-docs/project.json b/docs/nx-cloudflare-docs/project.json new file mode 100644 index 000000000..525e92ccb --- /dev/null +++ b/docs/nx-cloudflare-docs/project.json @@ -0,0 +1,65 @@ +{ + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "root": "docs/nx-cloudflare-docs", + "sourceRoot": "docs/nx-cloudflare-docs/src", + "projectType": "application", + "namedInputs": { + "default": ["{projectRoot}/**/*"], + "production": ["!{projectRoot}/**/*.spec.tsx"] + }, + "implicitDependencies": ["nx-cloudflare"], + "targets": { + "build": { + "inputs": ["production", "^production"], + "outputs": ["{workspaceRoot}/dist/docs/nx-cloudflare-docs"], + "command": "astro build", + "cache": true, + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + }, + "dev": { + "command": "astro dev", + "continuous": true, + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + }, + "preview": { + "command": "astro preview", + "continuous": true, + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + }, + "astro": { + "command": "astro", + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + }, + "wrangler-dev": { + "dependsOn": ["build"], + "command": "wrangler dev", + "continuous": true, + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + }, + "deploy": { + "dependsOn": ["build"], + "command": "wrangler deploy", + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + }, + "versions-upload": { + "dependsOn": ["build"], + "command": "wrangler versions upload", + "options": { + "cwd": "docs/nx-cloudflare-docs" + } + } + }, + "tags": ["scope:public", "type:docs"] +} diff --git a/docs/nx-cloudflare-docs/public/favicon.svg b/docs/nx-cloudflare-docs/public/favicon.svg new file mode 100644 index 000000000..92aead9e0 --- /dev/null +++ b/docs/nx-cloudflare-docs/public/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/docs/nx-cloudflare-docs/src/components/Head.astro b/docs/nx-cloudflare-docs/src/components/Head.astro new file mode 100644 index 000000000..c143b9119 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/components/Head.astro @@ -0,0 +1,27 @@ +--- +import { Font } from 'astro:assets'; +import { ClientRouter } from 'astro:transitions'; + +const { head } = Astro.locals.starlightRoute; +--- + +{head.map(({ tag: Tag, attrs, content }) => )} + + + + diff --git a/docs/nx-cloudflare-docs/src/components/Header.astro b/docs/nx-cloudflare-docs/src/components/Header.astro new file mode 100644 index 000000000..47f8f648e --- /dev/null +++ b/docs/nx-cloudflare-docs/src/components/Header.astro @@ -0,0 +1,43 @@ +--- +import PluginLogo from './PluginLogo.astro'; +--- + + + + diff --git a/docs/nx-cloudflare-docs/src/components/Pagination.astro b/docs/nx-cloudflare-docs/src/components/Pagination.astro new file mode 100644 index 000000000..449d7b23b --- /dev/null +++ b/docs/nx-cloudflare-docs/src/components/Pagination.astro @@ -0,0 +1,131 @@ +--- +const { dir, pagination, id } = Astro.locals.starlightRoute; +const { prev, next } = pagination; +const isRtl = dir === 'rtl'; +--- + +
+ + Was this page helpful? + + + + +
+ + + + + + diff --git a/docs/nx-cloudflare-docs/src/components/PluginLogo.astro b/docs/nx-cloudflare-docs/src/components/PluginLogo.astro new file mode 100644 index 000000000..c59adde03 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/components/PluginLogo.astro @@ -0,0 +1,50 @@ +--- +const { height = 22 } = Astro.props; +--- + + + + diff --git a/docs/nx-cloudflare-docs/src/components/Sidebar.astro b/docs/nx-cloudflare-docs/src/components/Sidebar.astro new file mode 100644 index 000000000..5b78bcb30 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/components/Sidebar.astro @@ -0,0 +1,120 @@ +--- +import config from 'virtual:starlight/user-config'; +import Search from 'virtual:starlight/components/Search'; +import SocialIcons from 'virtual:starlight/components/SocialIcons'; +import ThemeSelect from 'virtual:starlight/components/ThemeSelect'; +import SidebarPersister from '@astrojs/starlight/components/SidebarPersister.astro'; +import SidebarSublist from '@astrojs/starlight/components/SidebarSublist.astro'; +import PluginLogo from './PluginLogo.astro'; + +const { sidebar } = Astro.locals.starlightRoute; + +const shouldRenderSearch = + config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro'; +--- + +{/* ── Top chrome (desktop only) ──────────────────────────────────── */} + + +{/* ── Scrollable nav ─────────────────────────────────────────────── */} + + + + +{/* ── Bottom bar (all breakpoints) ────────────────────────────────── */} + + + diff --git a/docs/nx-cloudflare-docs/src/components/ThemeSelect.astro b/docs/nx-cloudflare-docs/src/components/ThemeSelect.astro new file mode 100644 index 000000000..dfab84dbf --- /dev/null +++ b/docs/nx-cloudflare-docs/src/components/ThemeSelect.astro @@ -0,0 +1,119 @@ +--- +--- + + + + + +{/* Inlined to avoid FOUC. Uses global scope from ThemeProvider.astro */} + + + + + diff --git a/docs/nx-cloudflare-docs/src/content.config.ts b/docs/nx-cloudflare-docs/src/content.config.ts new file mode 100644 index 000000000..6a7b7a02b --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/docs/nx-cloudflare-docs/src/content/docs/community/migration.md b/docs/nx-cloudflare-docs/src/content/docs/community/migration.md new file mode 100644 index 000000000..4df97f2dc --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/community/migration.md @@ -0,0 +1,95 @@ +--- +title: Migrate to 7.0.0 +description: How to migrate to @naxodev/nx-cloudflare 7.0.0 — inferred targets and Next.js removal. +--- + +import { Steps } from '@astrojs/starlight/components'; + +7.0.0 replaces the old `serve`/`deploy`/`publish`/`next-build` executors with +targets inferred from your Wrangler config, and removes the Next.js + webpack +integration entirely. Two migrations handle the transition: one deterministic, +one prompt-based. + +## Before you start + +- Commit any uncommitted work. The migration modifies `nx.json` and project + `project.json`/`package.json` files. +- Review the [inferred targets reference](/guides/targets-serve) to understand what + the new targets look like. + +## Steps + + + +1. **Generate the migration file** + + Run `nx migrate` against the new version: + + ```bash + bunx nx migrate @naxodev/nx-cloudflare + ``` + + Nx generates a `migrations.json` file listing the migrations to apply and + the dependency version bumps (Nx 23, Wrangler v4.98). Review it before + proceeding. + +2. **Apply the deterministic migration** + + The `update-7-0-0-move-to-inference` migration runs automatically. It + removes any project target whose executor is `@naxodev/nx-cloudflare:serve`, + `:deploy`, `:publish`, or `:next-build`, and registers + `@naxodev/nx-cloudflare/plugin` in `nx.json` so those targets are re-provided + as inferred targets. + + ```bash + bunx nx migrate --run-migrations + ``` + + If you had customized a removed target with executor options (e.g. `port`, + `vars`, `routes`, `compatibility*`), the migration logs a warning naming the + dropped option keys. Move that configuration into your Wrangler config + (`wrangler.jsonc`/`.toml`), where Wrangler reads it natively, or pass it as + command-line args to the inferred target. + +3. **Remove Next.js references** + + The `update-7-0-0-drop-nextjs` migration is prompt-based — it generates + instructions but does not modify files automatically. Search the workspace + for references to the deleted symbols and remove or replace them: + + - **`next.config.js` / `next.config.mjs`** — remove imports of `withNx` or + `composePlugins` from `@naxodev/nx-cloudflare`. If the config only existed + to wrap Next.js for Cloudflare via this plugin, delete the wrapper and keep + a plain Next.js config. + - **`package.json`** — drop any `@naxodev/nx-cloudflare`-based Next.js build + scripts that called the `next-build` executor or the webpack composition. + - **Choose a replacement path for Next.js on Cloudflare.** This plugin no + longer provides one. The Cloudflare-recommended approach is + [`@opennextjs/cloudflare`](https://opennext.js.org/cloudflare) (OpenNext), + which builds a Next.js app into a Cloudflare Worker. Migrate to it, or to + Cloudflare Pages, as appropriate. + + Non-Next.js Workers are unaffected — only touch projects that referenced the + removed symbols. + + + +## Verify + +Confirm the inferred targets resolve for each affected project: + +```bash +bunx nx show project +``` + +Check that `serve`, `deploy`, `typegen`, `version-upload`, and `tail` appear as +targets, and that no target references `@naxodev/nx-cloudflare:next-build`. + +## Next steps + +- [Inferred targets reference](/guides/targets-serve) — `serve`, `deploy`, `typegen`, + `version-upload`, `tail` +- [How Wrangler config inference works](/understanding/wrangler) — why targets + are inferred from your Wrangler config +- [Plugin options](/understanding/plugin-options) — customizing inferred target + names diff --git a/docs/nx-cloudflare-docs/src/content/docs/getting-started/installation.md b/docs/nx-cloudflare-docs/src/content/docs/getting-started/installation.md new file mode 100644 index 000000000..ebfe63e90 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/getting-started/installation.md @@ -0,0 +1,76 @@ +--- +title: Install Nx Cloudflare +description: How to install and configure @naxodev/nx-cloudflare in your workspace. +--- + +import { Steps } from '@astrojs/starlight/components'; + +## Prerequisites + +- **Node.js 20 or later** — required by Nx and Wrangler. +- An existing Nx workspace. If you don't have one, create it with + `bunx create-nx-workspace@latest`. +- A package manager: **bun**, npm, yarn, or pnpm. Examples below use `bunx`. + +## Steps + + + +1. **Add the plugin** + + The recommended way is `nx add`, which installs the package and runs the + [`init` generator](/guides/generators-init) to set up workspace-level + dependencies and register the inference plugin: + + ```bash + bunx nx add @naxodev/nx-cloudflare + ``` + + This installs Wrangler v4, `@cloudflare/workers-types`, and Vitest as + devDependencies, and adds `@naxodev/nx-cloudflare/plugin` to the `plugins` + array in `nx.json` so Worker targets are inferred automatically. + +2. **(Alternative) Install manually** + + If you prefer to control setup yourself, install the package and Wrangler + separately, then register the plugin in `nx.json`: + + ```bash + bun add -D @naxodev/nx-cloudflare wrangler + ``` + + Then add the plugin to `nx.json`: + + ```json title="nx.json" + { + "plugins": ["@naxodev/nx-cloudflare/plugin"] + } + ``` + + See [Plugin options](/understanding/plugin-options) for the object form if + you need to customize inferred target names. + +3. **Verify the plugin is registered** + + Confirm Nx recognizes the plugin by refreshing the project graph and + inspecting a Worker project (once you have one): + + ```bash + bunx nx reset + bunx nx show project + ``` + + The output should list `serve`, `deploy`, `typegen`, `version-upload`, and + `tail` targets. If you don't have a Worker yet, the + [Quick start](/getting-started/quick-start) walks through generating one. + + + +## Next steps + +- [Quick start](/getting-started/quick-start) — create, serve, and deploy your + first Worker. +- [application generator](/guides/generators-application) — scaffold a Worker + application with C3. +- [Plugin options](/understanding/plugin-options) — customize inferred target + names. diff --git a/docs/nx-cloudflare-docs/src/content/docs/getting-started/introduction.md b/docs/nx-cloudflare-docs/src/content/docs/getting-started/introduction.md new file mode 100644 index 000000000..2fbcee793 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/getting-started/introduction.md @@ -0,0 +1,27 @@ +--- +title: Introduction +description: What is Nx Cloudflare and what can it do for you? +--- + +`@naxodev/nx-cloudflare` is an Nx plugin for [Cloudflare Workers](https://developers.cloudflare.com/workers/). +It brings Workers into an Nx workspace so you can scaffold, serve, deploy, and +maintain Worker projects alongside the rest of your monorepo — with the caching, +affected-detection, and project graph that Nx provides. + +The plugin infers Worker lifecycle targets (`serve`, `deploy`, `typegen`, +`version-upload`, `tail`) directly from each project's Wrangler config, so there +are no hand-written `project.json` targets to maintain. Scaffolding is handled +by generators that wrap Cloudflare's [create-cloudflare (C3)](https://developers.cloudflare.com/workers/get-started/create-worker/) +CLI, producing Nx-ready projects with `wrangler.jsonc`, TypeScript, and Vitest +pre-configured. + +It's for teams and individuals already using Nx who want first-class Cloudflare +Workers support in their workspace — whether that's a single Worker or a fleet +of them shared across libraries, bindings, and shared logic. + +## Where to go next + +- New to the plugin? Walk through the [Quick start](/getting-started/quick-start) + to create, serve, and deploy a Worker in a few minutes. +- Already know what you need? See [Installation](/getting-started/installation) + to add the plugin to an existing workspace. diff --git a/docs/nx-cloudflare-docs/src/content/docs/getting-started/quick-start.md b/docs/nx-cloudflare-docs/src/content/docs/getting-started/quick-start.md new file mode 100644 index 000000000..4aac79f0d --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/getting-started/quick-start.md @@ -0,0 +1,121 @@ +--- +title: Create your first Cloudflare Worker +description: How to create, serve, and deploy a Cloudflare Worker with Nx. +--- + +import { Steps } from '@astrojs/starlight/components'; + +In this tutorial, we'll create a Cloudflare Worker, serve it locally, and deploy +it to Cloudflare — all from an Nx workspace. + +## Before you start + +- **Node.js 20 or later** — required by Nx and Wrangler. +- **A Cloudflare account** — needed for deployment. Sign up at + [dash.cloudflare.com](https://dash.cloudflare.com/sign-up). +- **Wrangler v4** — installed automatically when we add the plugin. + +## Compatibility + +| Nx version | Plugin version | +| ---------- | -------------- | +| 17.x | 1.x | +| 18.x | 2.x | +| 19.x | 3.x | +| 20.x | 4.x | +| 21.x | 5.x | +| 22–23.x | 6.x | + +Wrangler v4 is a peer dependency. The `init` generator installs it +automatically; if you add the plugin manually, install it with +`bun add -D wrangler`. + +## Steps + + + +1. **Add the plugin to our workspace** + + We'll use `nx add`, which installs the package and runs the + [`init` generator](/guides/generators-init) to set up workspace-level dependencies + and register the inference plugin in `nx.json`: + + ```bash + bunx nx add @naxodev/nx-cloudflare + ``` + + This installs Wrangler v4, `@cloudflare/workers-types`, and Vitest as + devDependencies, and adds `@naxodev/nx-cloudflare/plugin` to the `plugins` + array in `nx.json` so Worker targets are inferred automatically. + +2. **Generate a Worker** + + We'll scaffold a hello-world Worker using the + [application generator](/guides/generators-application), which wraps Cloudflare's + create-cloudflare (C3) CLI and makes the result Nx-ready: + + ```bash + bunx nx g @naxodev/nx-cloudflare:application my-worker --type=hello-world + ``` + + The generator creates a `my-worker/` directory with a `wrangler.jsonc` + config, a `src/index.ts` entry point, and a `package.json` that registers + the project with Nx. It also retargets the Wrangler `$schema` to the + workspace root and strips redundant package scripts. + +3. **Serve the Worker locally** + + Now we can run the Worker in a local dev server: + + ```bash + bunx nx serve my-worker + ``` + + This runs `wrangler dev` from the project root. The server is ready when + Wrangler prints `Ready on http://localhost:8787`. Open that URL to see the + Worker's response. + +4. **Deploy to Cloudflare** + + When we're ready to deploy, we run: + + ```bash + bunx nx deploy my-worker + ``` + + This runs `wrangler deploy`, which uploads the Worker to Cloudflare's edge + network. On first deploy, Wrangler opens a browser to authenticate with your + Cloudflare account. Pass Wrangler flags through after `--`: + + ```bash + bunx nx deploy my-worker -- --dry-run + ``` + + The `--dry-run` flag validates the deployment without publishing. + + + +## Verify + +Confirm the inferred targets resolved correctly: + +```bash +bunx nx show project my-worker +``` + +This lists `serve`, `deploy`, `typegen`, `version-upload`, and `tail`, +confirming the plugin registered the project. + +To verify the deployment, visit the Worker's URL. Wrangler prints the URL on +successful deploy (e.g. `https://my-worker..workers.dev`). + +## Next steps + +- [Application generator reference](/guides/generators-application) — all scaffolding + options (templates, frameworks, languages) +- [Inferred targets reference](/guides/targets-serve) — `serve`, `deploy`, `typegen`, + `version-upload`, `tail` +- [How Wrangler config inference works](/understanding/wrangler) — why the + plugin reads your Wrangler config +- [Plugin options](/understanding/plugin-options) — customizing inferred target + names diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/generators-application.md b/docs/nx-cloudflare-docs/src/content/docs/guides/generators-application.md new file mode 100644 index 000000000..a5cbe9a0c --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/generators-application.md @@ -0,0 +1,41 @@ +--- +title: application generator +description: Scaffold a Cloudflare Worker with create-cloudflare (C3) and make it Nx-ready. +--- + +The `create-cloudflare` generator wraps Cloudflare's [create-cloudflare (C3)](https://developers.cloudflare.com/workers/get-started/create-worker/) CLI to scaffold a Worker project, then makes it Nx-ready with Wrangler target inference and workspace-managed dependencies. + +**Aliases:** `c3`, `application`, `app` + +## Usage + +```bash +bunx nx g @naxodev/nx-cloudflare:application my-worker +``` + +## Options + +| Option | Type | Default | Description | +| ---------------- | ------------------------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `directory` | string | _(required)_ | The directory of the new application. Takes the first positional argument. | +| `name` | string | | The name of the application. Must match `^[a-zA-Z][^:]*$`. | +| `type` | string | | Worker template forwarded to C3 `--type` (e.g. `hello-world`, `hello-world-durable-object`, `scheduled`, `queues`, `openapi`). | +| `framework` | string | | Web framework forwarded to C3 `--framework` (e.g. `react`, `hono`, `next`, `astro`, `svelte`, `vue`). | +| `template` | string | | Remote git template forwarded to C3 `--template`. | +| `lang` | `ts` \| `js` \| `python` | `ts` | Language of the generated scaffold, forwarded to C3 `--lang`. | +| `c3Version` | string | `2.70.0` | Override the pinned create-cloudflare version to invoke. | +| `c3Args` | string[] | | Additional raw flags forwarded to C3. Generator-controlled flags (`git`, `deploy`, `open`, `auto-update`) cannot be overridden. | +| `tags` | string | | Comma-separated tags added to the application (used for linting). | +| `useProjectJson` | boolean | `false` | Write an explicit `project.json`. Off by default — the worker is registered from its `package.json` and Wrangler config via target inference. | +| `skipFormat` | boolean | `false` | Skip formatting files. | + +## Notes + +Provide exactly one of `type`, `framework`, or `template` to control the C3 scaffold non-interactively. If none are provided, C3's interactive prompts guide selection. + +## Next steps + +- [Inferred targets](/guides/targets-serve) — `serve`, `deploy`, `typegen`, `version-upload`, `tail` +- [Plugin options](/understanding/plugin-options) — customizing inferred target names +- [Wrangler config](/understanding/wrangler) — config formats and inference +- [library generator](/guides/generators-library) — scaffold a Worker library diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/generators-init.md b/docs/nx-cloudflare-docs/src/content/docs/guides/generators-init.md new file mode 100644 index 000000000..cbfb0f3fb --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/generators-init.md @@ -0,0 +1,45 @@ +--- +title: init generator +description: Initialize the Nx Cloudflare plugin in an existing workspace. +--- + +The `init` generator sets up workspace-level dependencies and plugin registration for Cloudflare Workers development with Nx, running automatically via `nx add @naxodev/nx-cloudflare` and from the `application` and `library` generators. + +## Usage + +```bash +bunx nx g @naxodev/nx-cloudflare:init +``` + +## Options + +| Option | Type | Default | Description | +| ---------------- | ---------------------------- | ------------ | ------------------------------------------------------ | +| `name` | string | _(required)_ | The name of the workspace. Forwarded to `@nx/js:init`. | +| `unitTestRunner` | `vitest` \| `jest` \| `none` | `vitest` | Test runner to use for unit tests. | +| `js` | boolean | `false` | Use JavaScript instead of TypeScript. | +| `skipFormat` | boolean | `false` | Skip formatting files. | + +## Installed dependencies + +The `init` generator runs `@nx/js:init` first, then adds the following packages: + +| Package | Scope | Pinned version | +| --------------------------------- | ------------- | --------------- | +| `tslib` | dependency | `^2.3.0` | +| `wrangler` | devDependency | `^4.98.0` | +| `@cloudflare/workers-types` | devDependency | `^4.20260606.1` | +| `@cloudflare/vitest-pool-workers` | devDependency | `^0.16.0` | +| `vitest` | devDependency | `^4.1.0` | + +It also registers `@naxodev/nx-cloudflare/plugin` in `nx.json` so that Worker lifecycle targets (`serve`, `deploy`, `typegen`, `version-upload`, `tail`) are inferred from Wrangler configs. + +## Notes + +The `init` generator does not re-add `@naxodev/nx-cloudflare` itself to `package.json` — the plugin invoking the generator is already installed. + +## Next steps + +- [application generator](/guides/generators-application) — scaffold a Worker application +- [library generator](/guides/generators-library) — scaffold a Worker library +- [Plugin options](/understanding/plugin-options) — inferred target names diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/generators-library.md b/docs/nx-cloudflare-docs/src/content/docs/guides/generators-library.md new file mode 100644 index 000000000..32b67ce5c --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/generators-library.md @@ -0,0 +1,49 @@ +--- +title: library generator +description: Generate a Cloudflare Worker library with Workers runtime types. +--- + +The `library` generator creates a Cloudflare Worker library — a shareable package with Workers runtime types, suitable for shared logic, bindings, or utilities consumed by Worker applications. + +**Alias:** `lib` + +## Usage + +```bash +bunx nx g @naxodev/nx-cloudflare:library my-worker-lib +``` + +## Options + +| Option | Type | Default | Description | +| ------------------------- | ----------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------- | +| `directory` | string | _(required)_ | The directory of the new library. Takes the first positional argument. | +| `name` | string | | The name of the library. Must match `^[a-zA-Z][^:]*$`. | +| `linter` | `eslint` \| `none` | `eslint` | The tool to use for running lint checks. | +| `unitTestRunner` | `vitest` \| `none` | _(prompted)_ | Test runner to use for unit tests. | +| `bundler` | `swc` \| `tsc` \| `vite` \| `esbuild` \| `none` | `tsc` | The bundler to use. `none` means the library is not buildable. | +| `publishable` | boolean | `false` | Generate a publishable library. | +| `importPath` | string | | The library name used to import it (e.g. `@myorg/my-lib`). Required for publishable libraries. | +| `js` | boolean | `false` | Generate JavaScript files rather than TypeScript files. | +| `strict` | boolean | `true` | Enable tsconfig strict mode. | +| `tags` | string | | Comma-separated tags added to the library (used for linting). | +| `minimal` | boolean | `false` | Generate a library with minimal setup. No README.md generated. | +| `simpleName` | boolean | `false` | Don't include the directory in the generated file name. | +| `config` | `workspace` \| `project` \| `npm-scripts` | `project` | Where to configure the project's executors. | +| `skipFormat` | boolean | `false` | Skip formatting files. | +| `skipPackageJson` | boolean | `false` | Do not add dependencies to `package.json`. | +| `skipTsConfig` | boolean | `false` | Do not update `tsconfig.json` for development experience. | +| `skipTypeCheck` | boolean | `false` | Skip TypeScript type checking for SWC compiler. | +| `setParserOptionsProject` | boolean | `false` | Configure the ESLint `parserOptions.project` option. Off by default for lint performance. | + +## Notes + +Publishable libraries require `importPath` and cannot use `bundler=none`. Non-publishable libraries have `bundler` forced to `none` (not buildable) regardless of the value passed. + +Worker libraries have no Wrangler config, so no inferred targets are generated (`serve`, `deploy`, `typegen`, etc. are not available). Workers runtime types come from `@cloudflare/workers-types` via `tsconfig.lib.json`, not a generated `worker-configuration.d.ts`. + +## Next steps + +- [application generator](/guides/generators-application) — scaffold a Worker application +- [init generator](/guides/generators-init) — workspace-level setup +- [Plugin options](/understanding/plugin-options) — inferred target names diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/targets-deploy.md b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-deploy.md new file mode 100644 index 000000000..a580fa9a5 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-deploy.md @@ -0,0 +1,31 @@ +--- +title: deploy +description: Inferred target that runs wrangler deploy to publish a Worker to Cloudflare's edge. +--- + +The `deploy` target runs `wrangler deploy` from the project root, publishing the Worker to Cloudflare's edge network. + +## Usage + +```bash +nx deploy +``` + +## Behavior + +- **Command:** `wrangler deploy` +- **Continuous:** no + +## Passing flags + +```bash +nx deploy -- --dry-run +nx deploy -- --name my-custom-worker +``` + +## Next steps + +- [version-upload target](/guides/targets-version-upload) for gradual deployments +- [Wrangler config and target inference](/understanding/wrangler) +- [Plugin options](/understanding/plugin-options) +- [`wrangler deploy` CLI docs](https://developers.cloudflare.com/workers/wrangler/commands/#deploy) diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/targets-serve.md b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-serve.md new file mode 100644 index 000000000..c175f1799 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-serve.md @@ -0,0 +1,34 @@ +--- +title: serve +description: Inferred target that runs wrangler dev to start a local Worker development server. +--- + +The `serve` target runs `wrangler dev` from the project root, starting a continuous local development server for the Worker. + +## Usage + +```bash +nx serve +``` + +## Behavior + +- **Command:** `wrangler dev` +- **Continuous:** yes +- **Ready signal:** considered ready when Wrangler prints `Ready on http://...`, so dependent tasks wait for the server to be listening. + +The dev server port is set via `dev.port` in the Wrangler config and defaults to `8787`. + +## Passing flags + +```bash +nx serve -- --remote +nx serve -- --ip 0.0.0.0 +``` + +## Next steps + +- [deploy target](/guides/targets-deploy) +- [Wrangler config and target inference](/understanding/wrangler) +- [Plugin options](/understanding/plugin-options) +- [`wrangler dev` CLI docs](https://developers.cloudflare.com/workers/wrangler/commands/#dev) diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/targets-tail.md b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-tail.md new file mode 100644 index 000000000..2b1a941d4 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-tail.md @@ -0,0 +1,32 @@ +--- +title: tail +description: Inferred target that runs wrangler tail to stream live logs from a deployed Worker. +--- + +The `tail` target runs `wrangler tail` from the project root, streaming live logs from a deployed Worker in real time. For local development, use [serve](/guides/targets-serve) instead and read the terminal output directly. + +## Usage + +```bash +nx tail +``` + +## Behavior + +- **Command:** `wrangler tail` +- **Continuous:** yes + +## Passing flags + +```bash +nx tail -- --status error +nx tail -- --format json +``` + +## Next steps + +- [serve target](/guides/targets-serve) +- [deploy target](/guides/targets-deploy) +- [Wrangler config and target inference](/understanding/wrangler) +- [Plugin options](/understanding/plugin-options) +- [`wrangler tail` CLI docs](https://developers.cloudflare.com/workers/wrangler/commands/#tail) diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/targets-typegen.md b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-typegen.md new file mode 100644 index 000000000..65ad879cb --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-typegen.md @@ -0,0 +1,35 @@ +--- +title: typegen +description: Inferred target that runs wrangler types to generate worker-configuration.d.ts. +--- + +The `typegen` target runs `wrangler types` from the project root, generating `worker-configuration.d.ts` — the typed `Env` interface and Workers runtime types derived from the Wrangler config. + +## Usage + +```bash +nx typegen +``` + +## Behavior + +- **Command:** `wrangler types` +- **Continuous:** no +- **Cached:** yes +- **Inputs:** project files, upstream project files, and the `wrangler` external dependency +- **Outputs:** `{projectRoot}/worker-configuration.d.ts` + +`worker-configuration.d.ts` is a generated artifact and is git-ignored. The `typegen` target is inferred only for Worker applications (projects with a Wrangler config); Worker libraries do not have one. + +## Passing flags + +```bash +nx typegen -- --name MyEnv +``` + +## Next steps + +- [serve target](/guides/targets-serve) +- [Wrangler config and target inference](/understanding/wrangler) +- [Plugin options](/understanding/plugin-options) +- [`wrangler types` CLI docs](https://developers.cloudflare.com/workers/wrangler/commands/#types) diff --git a/docs/nx-cloudflare-docs/src/content/docs/guides/targets-version-upload.md b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-version-upload.md new file mode 100644 index 000000000..95682ef12 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/guides/targets-version-upload.md @@ -0,0 +1,30 @@ +--- +title: version-upload +description: Inferred target that runs wrangler versions upload to publish a new Worker version. +--- + +The `version-upload` target runs `wrangler versions upload` from the project root, uploading a new version of the Worker to Cloudflare's Versions API. This is the foundation for gradual deployments — rolling out new versions incrementally and rolling back instantly. + +## Usage + +```bash +nx version-upload +``` + +## Behavior + +- **Command:** `wrangler versions upload` +- **Continuous:** no + +## Passing flags + +```bash +nx version-upload -- --message "fix: update handler" +``` + +## Next steps + +- [deploy target](/guides/targets-deploy) +- [Wrangler config and target inference](/understanding/wrangler) +- [Plugin options](/understanding/plugin-options) +- [Wrangler versions docs](https://developers.cloudflare.com/workers/wrangler/commands/#versions) diff --git a/docs/nx-cloudflare-docs/src/content/docs/index.mdx b/docs/nx-cloudflare-docs/src/content/docs/index.mdx new file mode 100644 index 000000000..dbbaccd1f --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/index.mdx @@ -0,0 +1,85 @@ +--- +title: Nx Cloudflare documentation +description: Nx plugin for Cloudflare Workers +template: splash +hero: + tagline: An Nx plugin for Cloudflare Workers +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; + + + +
+ + + nx-cloudflare - Nx plugin for Cloudflare Workers + +
+ An Nx plugin for [Cloudflare Workers](/getting-started/quick-start) with inferred + targets, C3-powered scaffolding, and Wrangler v4 support. Available on [npm](https://www.npmjs.com/package/@naxodev/nx-cloudflare). +
+ + The plugin is open source. See the [GitHub + repository](https://github.com/naxodev/oss/tree/main/packages/nx-cloudflare). + + + Join the [Discord server](https://discord.gg/zjDCGpKP2S) for discussion and + support. + +
+ +--- + +## Key Features + +
+
+

Inferred Worker Targets

+

+ Serve, deploy, typegen, version-upload, and tail targets are inferred from + your Wrangler config — no hand-written project.json targets needed. +

+
+ +{' '} + +
+

C3-Powered Scaffolding

+

+ The application generator wraps Cloudflare's create-cloudflare (C3) CLI, + then makes the scaffolded project Nx-ready. +

+
+ +{' '} + +
+

Wrangler v4 + JSONC

+

+ Generates wrangler.jsonc by default with $schema validation. Supports + jsonc, toml, and json config formats. +

+
+
+ +--- + +
+

Ready to Get Started?

+

+ Start building Cloudflare Workers with Nx +

+ +
diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/README.md b/docs/nx-cloudflare-docs/src/content/docs/reference/README.md new file mode 100644 index 000000000..707004587 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/README.md @@ -0,0 +1,30 @@ +--- +editUrl: false +next: false +prev: false +title: "@naxodev/nx-cloudflare" +--- + +## Interfaces + +- [CreateCloudflareGeneratorSchema](/reference/interfaces/createcloudflaregeneratorschema/) +- [InitGeneratorSchema](/reference/interfaces/initgeneratorschema/) +- [NxCloudflareLibraryGeneratorSchema](/reference/interfaces/nxcloudflarelibrarygeneratorschema/) + +## Functions + +- [createCloudflareGenerator](/reference/functions/createcloudflaregenerator/) +- [initGenerator](/reference/functions/initgenerator/) +- [libraryGenerator](/reference/functions/librarygenerator/) + +## References + +### applicationGenerator + +Renames and re-exports [createCloudflareGenerator](/reference/functions/createcloudflaregenerator/) + +*** + +### CloudflareApplicationGeneratorSchema + +Renames and re-exports [CreateCloudflareGeneratorSchema](/reference/interfaces/createcloudflaregeneratorschema/) diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/functions/createCloudflareGenerator.md b/docs/nx-cloudflare-docs/src/content/docs/reference/functions/createCloudflareGenerator.md new file mode 100644 index 000000000..a20e2ad61 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/functions/createCloudflareGenerator.md @@ -0,0 +1,24 @@ +--- +editUrl: false +next: false +prev: false +title: "createCloudflareGenerator" +--- + +> **createCloudflareGenerator**(`tree`, `schema`): `Promise`\<`GeneratorCallback`\> + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/generator.ts:29](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/generator.ts#L29) + +## Parameters + +### tree + +`Tree` + +### schema + +[`CreateCloudflareGeneratorSchema`](/reference/interfaces/createcloudflaregeneratorschema/) + +## Returns + +`Promise`\<`GeneratorCallback`\> diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/functions/initGenerator.md b/docs/nx-cloudflare-docs/src/content/docs/reference/functions/initGenerator.md new file mode 100644 index 000000000..1c74d72af --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/functions/initGenerator.md @@ -0,0 +1,24 @@ +--- +editUrl: false +next: false +prev: false +title: "initGenerator" +--- + +> **initGenerator**(`tree`, `schema`): `Promise`\<() => `Promise`\<`void`\>\> + +Defined in: [packages/nx-cloudflare/src/generators/init/generator.ts:18](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/init/generator.ts#L18) + +## Parameters + +### tree + +`Tree` + +### schema + +[`InitGeneratorSchema`](/reference/interfaces/initgeneratorschema/) + +## Returns + +`Promise`\<() => `Promise`\<`void`\>\> diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/functions/libraryGenerator.md b/docs/nx-cloudflare-docs/src/content/docs/reference/functions/libraryGenerator.md new file mode 100644 index 000000000..b311519c1 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/functions/libraryGenerator.md @@ -0,0 +1,24 @@ +--- +editUrl: false +next: false +prev: false +title: "libraryGenerator" +--- + +> **libraryGenerator**(`tree`, `schema`): `Promise`\<() => `Promise`\<`void`\>\> + +Defined in: [packages/nx-cloudflare/src/generators/library/generator.ts:34](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/generator.ts#L34) + +## Parameters + +### tree + +`Tree` + +### schema + +[`NxCloudflareLibraryGeneratorSchema`](/reference/interfaces/nxcloudflarelibrarygeneratorschema/) + +## Returns + +`Promise`\<() => `Promise`\<`void`\>\> diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/CreateCloudflareGeneratorSchema.md b/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/CreateCloudflareGeneratorSchema.md new file mode 100644 index 000000000..8e3cb0a93 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/CreateCloudflareGeneratorSchema.md @@ -0,0 +1,106 @@ +--- +editUrl: false +next: false +prev: false +title: "CreateCloudflareGeneratorSchema" +--- + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:4](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L4) + +## Properties + +### c3Args? + +> `optional` **c3Args?**: `string`[] + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:17](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L17) + +Raw passthrough flags for create-cloudflare. + +*** + +### c3Version? + +> `optional` **c3Version?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:15](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L15) + +Override the pinned create-cloudflare version. + +*** + +### directory + +> **directory**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:5](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L5) + +*** + +### framework? + +> `optional` **framework?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:10](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L10) + +Web framework, forwarded to C3 `--framework`. + +*** + +### lang? + +> `optional` **lang?**: `C3Lang` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:13](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L13) + +*** + +### name? + +> `optional` **name?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:6](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L6) + +*** + +### skipFormat? + +> `optional` **skipFormat?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:19](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L19) + +*** + +### tags? + +> `optional` **tags?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:18](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L18) + +*** + +### template? + +> `optional` **template?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:12](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L12) + +Remote git template, forwarded to C3 `--template`. + +*** + +### type? + +> `optional` **type?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:8](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L8) + +Worker template, forwarded to C3 `--type`. + +*** + +### useProjectJson? + +> `optional` **useProjectJson?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts:20](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/create-cloudflare/schema.d.ts#L20) diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/InitGeneratorSchema.md b/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/InitGeneratorSchema.md new file mode 100644 index 000000000..fd93e1afa --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/InitGeneratorSchema.md @@ -0,0 +1,32 @@ +--- +editUrl: false +next: false +prev: false +title: "InitGeneratorSchema" +--- + +Defined in: [packages/nx-cloudflare/src/generators/init/schema.d.ts:1](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/init/schema.d.ts#L1) + +## Properties + +### js? + +> `optional` **js?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/init/schema.d.ts:4](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/init/schema.d.ts#L4) + +*** + +### skipFormat? + +> `optional` **skipFormat?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/init/schema.d.ts:3](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/init/schema.d.ts#L3) + +*** + +### unitTestRunner? + +> `optional` **unitTestRunner?**: `"none"` \| `"vitest"` \| `"jest"` + +Defined in: [packages/nx-cloudflare/src/generators/init/schema.d.ts:2](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/init/schema.d.ts#L2) diff --git a/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/NxCloudflareLibraryGeneratorSchema.md b/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/NxCloudflareLibraryGeneratorSchema.md new file mode 100644 index 000000000..49369dee5 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/reference/interfaces/NxCloudflareLibraryGeneratorSchema.md @@ -0,0 +1,168 @@ +--- +editUrl: false +next: false +prev: false +title: "NxCloudflareLibraryGeneratorSchema" +--- + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:5](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L5) + +## Properties + +### bundler? + +> `optional` **bundler?**: `Bundler` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:20](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L20) + +*** + +### config? + +> `optional` **config?**: `"workspace"` \| `"project"` \| `"npm-scripts"` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:19](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L19) + +*** + +### directory + +> **directory**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:6](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L6) + +*** + +### importPath? + +> `optional` **importPath?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:17](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L17) + +*** + +### js? + +> `optional` **js?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:14](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L14) + +*** + +### linter? + +> `optional` **linter?**: `Linter` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:9](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L9) + +*** + +### minimal? + +> `optional` **minimal?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:22](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L22) + +*** + +### name? + +> `optional` **name?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:7](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L7) + +*** + +### publishable? + +> `optional` **publishable?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:16](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L16) + +*** + +### rootProject? + +> `optional` **rootProject?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:23](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L23) + +*** + +### setParserOptionsProject? + +> `optional` **setParserOptionsProject?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:18](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L18) + +*** + +### simpleName? + +> `optional` **simpleName?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:24](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L24) + +*** + +### skipFormat? + +> `optional` **skipFormat?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:8](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L8) + +*** + +### skipPackageJson? + +> `optional` **skipPackageJson?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:12](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L12) + +*** + +### skipTsConfig? + +> `optional` **skipTsConfig?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:11](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L11) + +*** + +### skipTypeCheck? + +> `optional` **skipTypeCheck?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:21](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L21) + +*** + +### strict? + +> `optional` **strict?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:15](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L15) + +*** + +### tags? + +> `optional` **tags?**: `string` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:10](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L10) + +*** + +### unitTestRunner? + +> `optional` **unitTestRunner?**: `"none"` \| `"vitest"` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:13](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L13) + +*** + +### useProjectJson? + +> `optional` **useProjectJson?**: `boolean` + +Defined in: [packages/nx-cloudflare/src/generators/library/schema.d.ts:25](https://github.com/naxodev/oss/blob/main/packages/nx-cloudflare/src/generators/library/schema.d.ts#L25) diff --git a/docs/nx-cloudflare-docs/src/content/docs/understanding/plugin-options.md b/docs/nx-cloudflare-docs/src/content/docs/understanding/plugin-options.md new file mode 100644 index 000000000..424ad37c4 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/understanding/plugin-options.md @@ -0,0 +1,57 @@ +--- +title: Plugin Options +description: CloudflarePluginOptions reference for the inference plugin registration. +--- + +`CloudflarePluginOptions` configures the target names inferred by the `@naxodev/nx-cloudflare/plugin` inference plugin. All options are optional — omitting them applies the defaults. + +## Registration + +The plugin is registered in `nx.json`. Both forms are supported. + +### String form (defaults only) + +```json title="nx.json" +{ + "plugins": ["@naxodev/nx-cloudflare/plugin"] +} +``` + +### Object form (custom target names) + +```json title="nx.json" +{ + "plugins": [ + { + "plugin": "@naxodev/nx-cloudflare/plugin", + "options": { + "serveTargetName": "dev", + "deployTargetName": "publish", + "typegenTargetName": "types", + "versionUploadTargetName": "upload-version", + "tailTargetName": "logs" + } + } + ] +} +``` + +## Options + +| Option | Type | Default | Description | +| ------------------------- | ------ | ---------------- | -------------------------------------------------------- | +| `serveTargetName` | string | `serve` | Name for the inferred `wrangler dev` target. | +| `deployTargetName` | string | `deploy` | Name for the inferred `wrangler deploy` target. | +| `typegenTargetName` | string | `typegen` | Name for the inferred `wrangler types` target. | +| `versionUploadTargetName` | string | `version-upload` | Name for the inferred `wrangler versions upload` target. | +| `tailTargetName` | string | `tail` | Name for the inferred `wrangler tail` target. | + +## Notes + +The `application` and `init` generators register the plugin idempotently, matching either the string or object form. Changing target names after projects exist takes effect on the next Nx graph refresh — update any scripts, CI pipelines, or documentation that reference the old names. + +## Next steps + +- [Inferred targets](/guides/targets-serve) — `serve`, `deploy`, `typegen`, `version-upload`, `tail` +- [Wrangler config](/understanding/wrangler) — config formats and inference +- [application generator](/guides/generators-application) — scaffold a Worker application diff --git a/docs/nx-cloudflare-docs/src/content/docs/understanding/wrangler.md b/docs/nx-cloudflare-docs/src/content/docs/understanding/wrangler.md new file mode 100644 index 000000000..65cd762ed --- /dev/null +++ b/docs/nx-cloudflare-docs/src/content/docs/understanding/wrangler.md @@ -0,0 +1,119 @@ +--- +title: How Wrangler config inference works +description: Why the inference plugin reads your Wrangler config and what it looks for. +--- + +The `@naxodev/nx-cloudflare/plugin` inference plugin detects Wrangler config +files and infers Worker lifecycle targets from them. Understanding why it works +the way it does helps when something goes wrong — a project with no targets, a +broken `$schema`, or a config the plugin silently skips. + +## Why wrangler.jsonc is the default format + +The `application` generator scaffolds `wrangler.jsonc` because Cloudflare +recommends JSONC as the primary config format. Some newer Wrangler features are +only available in JSONC and JSON — TOML support is maintained for backward +compatibility but lags behind. + +The inference plugin accepts all three formats (`wrangler.jsonc`, +`wrangler.toml`, `wrangler.json`), but JSONC has a practical advantage in the +plugin: JSONC files are parsed with a JSONC-aware parser (Nx's `parseJson`), +so comments and trailing commas don't cause a parse failure. TOML files get a +lighter check — the plugin has no TOML parser, so it only verifies the file is +non-empty. A syntactically broken `wrangler.toml` passes the plugin's gate and +fails later at Wrangler runtime, while a broken `wrangler.jsonc` is caught and +skipped with a warning during graph construction. + +## Why $schema retargeting matters in monorepos + +C3 scaffolds a `wrangler.jsonc` with a `$schema` pointing at +`./node_modules/wrangler/config-schema.json`. In a standalone project this works +because Wrangler is installed locally. In a monorepo with hoisted dependencies, +Wrangler lives at the workspace root — the project-local `node_modules` doesn't +exist, and editors can't resolve the schema. + +The `application` generator retargets the `$schema` to the workspace root using +`offsetFromRoot`: + +```jsonc title="wrangler.jsonc" +{ + "$schema": "../../node_modules/wrangler/config-schema.json", + "name": "my-worker", + "compatibility_date": "2026-06-05", + "main": "src/index.ts" +} +``` + +The retargeting is done as a string replace that preserves JSONC comments, not +a full JSON round-trip. If you create a Wrangler config manually in a monorepo, +point the `$schema` at the workspace-root `node_modules`, not the project-local +one — otherwise editor validation and autocomplete break silently. + +## Why a sibling project file is required + +The inference plugin matches `**/wrangler.{toml,jsonc,json}`, but not every +match is a project root. A `wrangler.toml` in a subdirectory of a Worker project +(e.g. a config fragment, a test fixture) is not an Nx project. To avoid +inferring spurious targets, the plugin checks whether the config's directory +contains a `project.json` or `package.json`. If neither is present, the file is +ignored — no targets are inferred, no warning is logged. + +This is why the `application` generator writes a `package.json` by default +(rather than only a `project.json`): the package.json is the project's source of +truth in the TypeScript solution setup, and it satisfies the inference gate. The +optional `useProjectJson` flag writes a `project.json` instead, which also +satisfies the gate. Either file works; the plugin checks for either. + +## Why empty and unparseable configs are skipped + +The plugin validates each config file before inferring targets. The gate is +structural, not semantic: it checks that the file is readable and parseable, not +that the contents make sense for Wrangler. This is deliberate — Wrangler +validates its own config at runtime, and duplicating that validation in the +plugin would couple the plugin to Wrangler's schema and create maintenance +burden. + +Three cases are skipped with a warning: + +- **Unreadable files** — a permissions error, a broken symlink, or a race + condition. The warning names the file and the error. +- **Empty `.toml` files** — a zero-length or whitespace-only `wrangler.toml`. + Since there's no TOML parser, non-empty is the only available proxy for + "usable." +- **Unparseable `.json`/`.jsonc` files** — a syntax error that fails `parseJson`. + The warning names the file and the parse error. + +A parseable but minimal config (e.g. `{}`) is accepted, because Wrangler fills +in defaults at runtime. The plugin doesn't second-guess Wrangler's config +semantics. + +## How compatibility_date and compatibility_flags affect typegen + +The `typegen` target runs `wrangler types`, which generates +`worker-configuration.d.ts` — the typed `Env` interface and Workers runtime +types. Two Wrangler config settings shape that output: + +- **`compatibility_date`** — controls which Workers runtime features are + available. Setting it to a recent date unlocks newer APIs in the generated + types. +- **`compatibility_flags`** — opt-in flags like `nodejs_compat` that change + which runtime types are present. + +Because these settings affect the generated types, changing them requires +re-running `typegen` to refresh `worker-configuration.d.ts`. The `typegen` +target is cached and keyed on project files plus the installed `wrangler` +version, so Nx re-runs it when the Wrangler config changes. + +See the [typegen target reference](/guides/targets-typegen) for the full target +behavior, and the [Cloudflare Wrangler configuration docs](https://developers.cloudflare.com/workers/wrangler/configuration/) +for the complete config schema. + +## Why target names are configurable + +The plugin infers five targets with default names (`serve`, `deploy`, `typegen`, +`version-upload`, `tail`). These names are configurable via +`CloudflarePluginOptions` because workspaces may have existing targets with the +same name (e.g. a `serve` target from `@nx/vite`), or may follow different +naming conventions. The plugin accepts options in `nx.json` to rename any or +all inferred targets. See the [plugin options reference](/understanding/plugin-options) +for the exact shape and defaults. diff --git a/docs/nx-cloudflare-docs/src/env.d.ts b/docs/nx-cloudflare-docs/src/env.d.ts new file mode 100644 index 000000000..4ca6d2689 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/env.d.ts @@ -0,0 +1,16 @@ +/// + +declare module 'virtual:starlight/components/Search' { + const Search: typeof import('@astrojs/starlight/components').Search; + export default Search; +} + +declare module 'virtual:starlight/components/SocialIcons' { + const SocialIcons: typeof import('@astrojs/starlight/components').SocialIcons; + export default SocialIcons; +} + +declare module 'virtual:starlight/components/ThemeSelect' { + const ThemeSelect: typeof import('@astrojs/starlight/components').ThemeSelect; + export default ThemeSelect; +} diff --git a/docs/nx-cloudflare-docs/src/lib/code-blocks.ts b/docs/nx-cloudflare-docs/src/lib/code-blocks.ts new file mode 100644 index 000000000..98c09a31e --- /dev/null +++ b/docs/nx-cloudflare-docs/src/lib/code-blocks.ts @@ -0,0 +1,55 @@ +const COPY_ICON = ``; +const CHECK_ICON = ``; +const ERROR_ICON = ``; + +/** Enhance all `.astro-code` blocks with copy buttons and optional title bars. Idempotent. */ +export function enhanceCodeBlocks(root: ParentNode = document): void { + root.querySelectorAll('.astro-code').forEach((block) => { + if (block.parentElement?.classList.contains('code-block')) return; + + const wrapper = document.createElement('div'); + wrapper.className = 'code-block'; + + const title = block.getAttribute('data-title') || ''; + if (title) { + const header = document.createElement('div'); + header.className = 'code-block-header'; + const titleSpan = document.createElement('span'); + titleSpan.className = 'code-block-title'; + titleSpan.textContent = title; + header.appendChild(titleSpan); + wrapper.appendChild(header); + } + + const copyBtn = document.createElement('button'); + copyBtn.className = 'code-copy-btn'; + copyBtn.type = 'button'; + copyBtn.setAttribute('aria-label', 'Copy to clipboard'); + copyBtn.innerHTML = COPY_ICON; + copyBtn.addEventListener('click', async () => { + const code = + block.querySelector('code')?.textContent || block.textContent || ''; + try { + await navigator.clipboard.writeText(code); + copyBtn.innerHTML = CHECK_ICON; + setTimeout(() => { + copyBtn.innerHTML = COPY_ICON; + }, 2000); + } catch { + copyBtn.innerHTML = ERROR_ICON; + copyBtn.setAttribute( + 'aria-label', + 'Copy failed — try selecting text manually' + ); + setTimeout(() => { + copyBtn.innerHTML = COPY_ICON; + copyBtn.setAttribute('aria-label', 'Copy to clipboard'); + }, 2000); + } + }); + + block.parentNode!.insertBefore(wrapper, block); + wrapper.appendChild(block); + wrapper.appendChild(copyBtn); + }); +} diff --git a/docs/nx-cloudflare-docs/src/lib/copy-for-ai.ts b/docs/nx-cloudflare-docs/src/lib/copy-for-ai.ts new file mode 100644 index 000000000..e87111bb6 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/lib/copy-for-ai.ts @@ -0,0 +1,61 @@ +/** Convert a DOM element's content to a markdown string. */ +export function domToMarkdown(root: Element): string { + const lines: string[] = []; + + root + .querySelectorAll('h1, h2, h3, h4, h5, h6, p, li, pre code, blockquote') + .forEach((el) => { + const tag = el.tagName.toLowerCase(); + if (tag === 'code' && el.parentElement?.tagName === 'PRE') { + const lang = el.className?.match(/language-(\w+)/)?.[1] || ''; + lines.push('```' + lang, el.textContent?.trim() || '', '```', ''); + } else if (tag.startsWith('h')) { + const level = '#'.repeat(parseInt(tag[1])); + lines.push(`${level} ${el.textContent?.trim()}`, ''); + } else if (tag === 'li') { + lines.push(`- ${el.textContent?.trim()}`); + } else if (tag === 'blockquote') { + lines.push(`> ${el.textContent?.trim()}`, ''); + } else { + lines.push(el.textContent?.trim() || '', ''); + } + }); + + return lines.join('\n').replace(/\n{3,}/g, '\n\n'); +} + +const BOUND_ATTR = 'data-copy-for-ai-bound'; + +/** Attach click handlers to all `.copy-for-ai-btn` elements on the page. Idempotent. */ +export function initCopyForAi(): void { + document.querySelectorAll('.copy-for-ai-btn').forEach((btn) => { + if (btn.hasAttribute(BOUND_ATTR)) return; + btn.setAttribute(BOUND_ATTR, ''); + + let resetTimer: ReturnType | undefined; + + btn.addEventListener('click', async () => { + const content = document.querySelector('.sl-markdown-content'); + if (!content) return; + + const title = document.querySelector('h1')?.textContent?.trim() || ''; + const url = window.location.href; + + const markdown = `# ${title}\nSource: ${url}\n\n${domToMarkdown( + content + )}`; + + clearTimeout(resetTimer); + const original = btn.innerHTML; + try { + await navigator.clipboard.writeText(markdown); + btn.innerHTML = ` Copied!`; + } catch { + btn.innerHTML = ` Copy failed`; + } + resetTimer = setTimeout(() => { + btn.innerHTML = original; + }, 2000); + }); + }); +} diff --git a/docs/nx-cloudflare-docs/src/lib/page-feedback.ts b/docs/nx-cloudflare-docs/src/lib/page-feedback.ts new file mode 100644 index 000000000..4c6d61e20 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/lib/page-feedback.ts @@ -0,0 +1,45 @@ +import { safeGetItem, safeSetItem } from './preferences'; + +class PageFeedback extends HTMLElement { + #ac!: AbortController; + + connectedCallback() { + this.#ac = new AbortController(); + const { signal } = this.#ac; + const pageId = this.dataset.pageId; + const stored = safeGetItem(`feedback:${pageId}`); + + if (stored) { + const btn = [...this.querySelectorAll('.feedback-btn')].find( + (b) => b.dataset.value === stored + ); + if (btn) { + btn.setAttribute('data-selected', 'true'); + btn.setAttribute('aria-pressed', 'true'); + } + } + + this.querySelectorAll('.feedback-btn').forEach((btn) => { + btn.addEventListener( + 'click', + () => { + const value = (btn as HTMLElement).dataset.value; + this.querySelectorAll('.feedback-btn').forEach((b) => { + b.removeAttribute('data-selected'); + b.setAttribute('aria-pressed', 'false'); + }); + btn.setAttribute('data-selected', 'true'); + btn.setAttribute('aria-pressed', 'true'); + safeSetItem(`feedback:${pageId}`, value || ''); + }, + { signal } + ); + }); + } + + disconnectedCallback() { + this.#ac.abort(); + } +} + +customElements.define('page-feedback', PageFeedback); diff --git a/docs/nx-cloudflare-docs/src/lib/preferences.ts b/docs/nx-cloudflare-docs/src/lib/preferences.ts new file mode 100644 index 000000000..25c3bd32e --- /dev/null +++ b/docs/nx-cloudflare-docs/src/lib/preferences.ts @@ -0,0 +1,17 @@ +/** Read from localStorage, returning null if storage is unavailable. */ +export function safeGetItem(key: string): string | null { + try { + return localStorage.getItem(key); + } catch { + return null; + } +} + +/** Write to localStorage, silently failing if storage is unavailable. */ +export function safeSetItem(key: string, value: string): void { + try { + localStorage.setItem(key, value); + } catch { + /* storage unavailable */ + } +} diff --git a/docs/nx-cloudflare-docs/src/lib/toc-path.ts b/docs/nx-cloudflare-docs/src/lib/toc-path.ts new file mode 100644 index 000000000..764439c7c --- /dev/null +++ b/docs/nx-cloudflare-docs/src/lib/toc-path.ts @@ -0,0 +1,175 @@ +export interface Point { + x: number; + y: number; +} + +/** Build an SVG path string with cubic bezier curves connecting points. */ +export function buildSerpentinePath(points: Point[]): string { + if (points.length === 0) return ''; + let d = `M ${points[0].x},${points[0].y}`; + for (let i = 1; i < points.length; i++) { + const prev = points[i - 1]; + const curr = points[i]; + const midY = (prev.y + curr.y) / 2; + d += ` C ${prev.x},${midY} ${curr.x},${midY} ${curr.x},${curr.y}`; + } + return d; +} + +/** + * Given heading positions (as getBoundingClientRect().top values) and scroll + * metrics, return the index of the active heading. + * + * Near the bottom of the page, the activation offset smoothly expands from + * baseOffset to viewportHeight/2 so headings that can't physically reach the + * base offset still get their turn. + */ +export function resolveActiveIndex( + headingTops: number[], + scrollY: number, + scrollHeight: number, + viewportHeight: number, + baseOffset = 100, + nearBottomRatio = 0.6 +): number { + if (headingTops.length === 0) return 0; + + const maxScroll = scrollHeight - viewportHeight; + const distToBottom = Math.max(0, maxScroll - scrollY); + const nearBottomZone = viewportHeight * nearBottomRatio; + + const offset = + distToBottom < nearBottomZone + ? baseOffset + + (1 - distToBottom / nearBottomZone) * (viewportHeight / 2 - baseOffset) + : baseOffset; + + let active = 0; + for (let i = 0; i < headingTops.length; i++) { + if (headingTops[i] <= offset) active = i; + } + return active; +} + +// ── DOM orchestration ───────────────────────────────────────────── + +let cleanup: (() => void) | null = null; + +/** Initialize the ToC SVG serpentine indicator and scroll tracking. */ +export function initTocPath(): void { + cleanup?.(); + cleanup = null; + + const toc = document.querySelector('starlight-toc nav > ul'); + if (!toc) return; + + const links = [...toc.querySelectorAll('a')]; + if (links.length < 2) return; + + if (toc.parentElement?.classList.contains('toc-items-wrapper')) return; + + const wrapper = document.createElement('div'); + wrapper.className = 'toc-items-wrapper'; + toc.parentNode!.insertBefore(wrapper, toc); + wrapper.appendChild(toc); + + const ns = 'http://www.w3.org/2000/svg'; + const svg = document.createElementNS(ns, 'svg'); + svg.classList.add('toc-path-svg'); + svg.setAttribute('aria-hidden', 'true'); + + const bgPath = document.createElementNS(ns, 'path'); + bgPath.classList.add('toc-path-bg'); + const activePath = document.createElementNS(ns, 'path'); + activePath.classList.add('toc-path-active'); + svg.append(bgPath, activePath); + wrapper.prepend(svg); + + let points: Point[] = []; + + function buildPath() { + const wRect = wrapper.getBoundingClientRect(); + + points = links.map((link) => { + const rect = link.getBoundingClientRect(); + return { + x: Math.max(2, rect.left - wRect.left - 8), + y: rect.top - wRect.top + rect.height / 2, + }; + }); + + const svgW = Math.max(16, ...points.map((p) => p.x + 4)); + const svgH = wRect.height; + svg.setAttribute('width', String(svgW)); + svg.setAttribute('height', String(svgH)); + svg.setAttribute('viewBox', `0 0 ${svgW} ${svgH}`); + + const d = buildSerpentinePath(points); + bgPath.setAttribute('d', d); + activePath.setAttribute('d', d); + } + + buildPath(); + + function getActiveLink(): HTMLAnchorElement { + const headingTops = links.map((link) => { + const id = decodeURIComponent(link.hash.slice(1)); + const el = document.getElementById(id); + return el ? el.getBoundingClientRect().top : Infinity; + }); + + const idx = resolveActiveIndex( + headingTops, + window.scrollY, + document.documentElement.scrollHeight, + window.innerHeight + ); + return links[idx]; + } + + function update() { + const activeLink = getActiveLink(); + + links.forEach((l) => l.classList.remove('toc-active')); + activeLink.classList.add('toc-active'); + + const idx = links.indexOf(activeLink); + if (idx >= 0 && points[idx]) { + const clipY = points[idx].y + 4; + activePath.style.clipPath = `polygon(0 0, 100% 0, 100% ${clipY}px, 0 ${clipY}px)`; + } + } + + update(); + + const ro = new ResizeObserver(() => { + buildPath(); + update(); + }); + ro.observe(wrapper); + + // Use window.AbortController so the signal is owned by the same Window + // object that owns the event target — required for jsdom compatibility. + const ac = new window.AbortController(); + let scrollTimer: ReturnType | undefined; + window.addEventListener( + 'scroll', + () => { + clearTimeout(scrollTimer); + scrollTimer = setTimeout(update, 30); + }, + { passive: true, signal: ac.signal } + ); + + cleanup = () => { + clearTimeout(scrollTimer); + ac.abort(); + ro.disconnect(); + }; +} + +/** Tear down scroll listener and ResizeObserver. Safe to call when not initialized. */ +export function cleanupTocPath(): void { + cleanup?.(); + cleanup = null; +} diff --git a/docs/nx-cloudflare-docs/src/pages/404.astro b/docs/nx-cloudflare-docs/src/pages/404.astro new file mode 100644 index 000000000..0b840e201 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/pages/404.astro @@ -0,0 +1,232 @@ +--- +import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; +import { Icon } from '@astrojs/starlight/components'; +--- + + +
+
+
+
404
+
+ ☁️ + + 🚀 +
+
+ +

Oops! Page Not Found

+ +
+

Here's what you can do:

+
+
+ +

Go Home

+

Start fresh from our homepage

+ Take me home +
+ +
+ +

Browse Docs

+

Explore Nx Cloudflare documentation

+ View docs +
+ +
+ +

Report Issue

+

Found a broken link? Let us know!

+ Report bug +
+
+
+
+
+ + +
diff --git a/docs/nx-cloudflare-docs/src/styles/code-blocks.css b/docs/nx-cloudflare-docs/src/styles/code-blocks.css new file mode 100644 index 000000000..11fe1f3dd --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/code-blocks.css @@ -0,0 +1,133 @@ +/* ── Code blocks: Shiki with glass treatment ───────────────────── */ + +/* Wrapper added by JS (code-blocks.ts) */ +.code-block { + position: relative; + margin: 1rem 0; +} + +/* Title bar (file tab) */ +.code-block-header { + display: flex; + align-items: center; + padding: 0.5rem 1rem; + font-family: var(--font-code, 'JetBrains Mono'), monospace; + font-size: 0.75rem; + font-weight: 500; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.5rem 0.5rem 0 0; +} + +:root[data-theme='dark'] .code-block-header { + background: rgba(10, 25, 50, 0.5); + color: #7a9ab5; +} + +:root[data-theme='light'] .code-block-header { + background: rgba(230, 225, 218, 0.6); + color: #5a7a95; + border-bottom-color: rgba(10, 30, 53, 0.08); +} + +.code-block-header + .astro-code { + border-top-left-radius: 0; + border-top-right-radius: 0; + margin-top: 0; +} + +/* Copy button */ +.code-copy-btn { + position: absolute; + top: 0.5rem; + right: 0.5rem; + display: flex; + align-items: center; + justify-content: center; + width: 2rem; + height: 2rem; + padding: 0; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 0.375rem; + background: rgba(255, 255, 255, 0.05); + color: var(--sl-color-gray-3); + cursor: pointer; + opacity: 0; + pointer-events: none; + transition: opacity 0.15s, color 0.15s, background 0.15s; +} + +.code-block:hover .code-copy-btn, +.code-block:focus-within .code-copy-btn, +.code-copy-btn:focus-visible { + opacity: 1; + pointer-events: auto; +} + +@media (hover: none), (pointer: coarse) { + .code-copy-btn { + opacity: 1; + pointer-events: auto; + } +} + +.code-copy-btn:hover { + color: var(--color-accent-500); + background: color-mix(in srgb, var(--color-accent-500) 10%, transparent); + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); +} + +/* If there's a header, push copy button below it */ +.code-block-header ~ .code-copy-btn { + top: calc(0.5rem + 2rem + 1px); +} + +:root[data-theme='light'] .code-copy-btn { + border-color: rgba(10, 30, 53, 0.1); + background: rgba(255, 255, 255, 0.6); +} + +:root[data-theme='light'] .code-copy-btn:hover { + color: var(--color-accent-500); + background: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); +} + +/* Base code block styling */ +.astro-code { + padding: 1rem 1.25rem; + border-radius: 0.5rem; + font-family: var(--font-code, 'JetBrains Mono'), monospace; + font-size: 0.875rem; + line-height: 1.7; + overflow-x: auto; + tab-size: 2; + margin: 0; +} + +/* Shiki inlines styles on elements — !important is the only + way to override inline styles and apply our glass treatment. */ +:root[data-theme='dark'] .astro-code, +:root[data-theme='dark'] .astro-code span { + color: var(--shiki-dark) !important; + background-color: transparent !important; +} + +:root[data-theme='dark'] .astro-code { + background: rgba(15, 43, 74, 0.4) !important; + border: 1px solid rgba(255, 255, 255, 0.08); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 4px 24px rgba(0, 0, 0, 0.25); +} + +:root[data-theme='light'] .astro-code, +:root[data-theme='light'] .astro-code span { + color: var(--shiki-light) !important; + background-color: transparent !important; +} + +:root[data-theme='light'] .astro-code { + background: rgba(240, 237, 232, 0.5) !important; + border: 1px solid rgba(10, 30, 53, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), + 0 4px 24px rgba(0, 0, 0, 0.06); +} diff --git a/docs/nx-cloudflare-docs/src/styles/components.css b/docs/nx-cloudflare-docs/src/styles/components.css new file mode 100644 index 000000000..18569f570 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/components.css @@ -0,0 +1,235 @@ +/* ── Content components: inline code, cards, links, asides ──────── */ + +/* Inline code pills */ +.sl-markdown-content :not(pre) > code { + padding: 0.1em 0.4em; + border-radius: 0.3rem; + font-size: 0.875em; +} + +:root[data-theme='dark'] .sl-markdown-content :not(pre) > code { + background: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border: 1px solid color-mix(in srgb, var(--color-accent-500) 12%, transparent); + /* Bespoke light tint (brighter than accent-500) for legibility on the dark bg */ + color: #fb923c; +} + +:root[data-theme='light'] .sl-markdown-content :not(pre) > code { + background: color-mix(in srgb, var(--color-accent-500) 6%, transparent); + border: 1px solid color-mix(in srgb, var(--color-accent-500) 10%, transparent); + /* Darker brand shade: accent-500 fails AA contrast on the light bg */ + color: var(--color-accent-700); +} + +/* Glass cards (Starlight Card components) — unlayered CSS overrides + Starlight's layered defaults per cascade layer best practices. */ +:root[data-theme='dark'] .card { + background: rgba(10, 30, 53, 0.6); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.75rem; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 4px 24px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(8px); + transition: border-color 0.2s, box-shadow 0.2s; +} + +:root[data-theme='dark'] .card:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 15%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), + 0 4px 24px rgba(0, 0, 0, 0.2), + 0 0 20px color-mix(in srgb, var(--color-accent-500) 6%, transparent); +} + +:root[data-theme='light'] .card { + background: rgba(255, 255, 255, 0.6); + border: 1px solid rgba(10, 30, 53, 0.08); + border-radius: 0.75rem; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), + 0 4px 24px rgba(0, 0, 0, 0.06); + transition: border-color 0.2s, box-shadow 0.2s; +} + +:root[data-theme='light'] .card:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 15%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8), + 0 4px 24px rgba(0, 0, 0, 0.06), + 0 0 20px color-mix(in srgb, var(--color-accent-500) 6%, transparent); +} + +/* Link glow on hover */ +.sl-markdown-content a:not([class]) { + transition: color 0.15s, text-shadow 0.15s; +} + +:root[data-theme='dark'] .sl-markdown-content a:not([class]):hover { + text-shadow: 0 0 12px + color-mix(in srgb, var(--color-accent-500) 30%, transparent); +} + +:root[data-theme='light'] .sl-markdown-content a:not([class]):hover { + text-shadow: 0 0 12px + color-mix(in srgb, var(--color-accent-500) 15%, transparent); +} + +/* Asides/Callouts: glass-card treatment */ +:root[data-theme='dark'] .starlight-aside { + background: rgba(10, 30, 53, 0.6); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 0.75rem; + border-inline-start-width: 3px; +} + +:root[data-theme='light'] .starlight-aside { + background: rgba(10, 30, 53, 0.03); + border: 1px solid rgba(10, 30, 53, 0.08); + border-radius: 0.75rem; + border-inline-start-width: 3px; +} + +/* ── Search dialog ───────────────────────────────────────────────── */ + +site-search dialog { + opacity: 0; + transform: scale(0.95) translateY(-12px); + transition: opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1), + transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), + display 0.25s ease-out allow-discrete; +} + +site-search dialog[open] { + opacity: 1; + transform: scale(1) translateY(0); +} + +@starting-style { + site-search dialog[open] { + opacity: 0; + transform: scale(0.95) translateY(-12px); + } +} + +:root[data-theme='dark'] site-search dialog { + background: rgba(10, 20, 40, 0.85); + backdrop-filter: blur(20px) saturate(1.2); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 0.75rem; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6), 0 0 1px rgba(255, 255, 255, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.04); +} + +:root[data-theme='light'] site-search dialog { + background: rgba(254, 252, 248, 0.9); + backdrop-filter: blur(20px) saturate(1.2); + border: 1px solid rgba(10, 30, 53, 0.1); + border-radius: 0.75rem; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.12), 0 0 1px rgba(10, 30, 53, 0.08); +} + +site-search dialog::backdrop { + background-color: rgba(5, 8, 16, 0); + transition: background-color 0.25s ease-out, + display 0.25s ease-out allow-discrete; +} + +site-search dialog[open]::backdrop { + background-color: rgba(5, 8, 16, 0.75); +} + +@starting-style { + site-search dialog[open]::backdrop { + background-color: rgba(5, 8, 16, 0); + } +} + +:root[data-theme='light'] site-search dialog[open]::backdrop { + background-color: rgba(10, 30, 53, 0.3); +} + +.sidebar-search button[data-open-modal] kbd { + display: inline-flex; + font-family: var(--font-mono); + font-size: 0.65rem; + padding: 0.1em 0.4em; + border-radius: 0.25rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.05); + margin-inline-start: auto; +} + +/* ── Feedback buttons ────────────────────────────────────────────── */ + +.feedback-btn { + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.35rem 0.75rem; + border-radius: 0.5rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.03); + color: var(--sl-color-gray-2); + cursor: pointer; + font-size: 0.8rem; + transition: border-color 0.15s, background-color 0.15s, color 0.15s; +} + +.feedback-btn:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 6%, transparent); + color: var(--color-accent-500); +} + +.feedback-btn[data-selected='true'] { + border-color: color-mix(in srgb, var(--color-accent-500) 30%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 10%, transparent); + color: var(--color-accent-500); +} + +:root[data-theme='light'] .feedback-btn { + border-color: rgba(10, 30, 53, 0.12); + background: rgba(10, 30, 53, 0.03); +} + +:root[data-theme='light'] .feedback-btn:hover { + border-color: color-mix(in srgb, var(--color-accent-500) 20%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 6%, transparent); + color: var(--color-accent-500); +} + +:root[data-theme='light'] .feedback-btn[data-selected='true'] { + border-color: color-mix(in srgb, var(--color-accent-500) 30%, transparent); + background: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + color: var(--color-accent-500); +} + +/* ── Focus indicators (keyboard accessibility) ──────────────────── */ + +:focus-visible { + outline: 2px solid var(--color-accent-500); + outline-offset: 2px; + border-radius: 0.25rem; +} + +:root[data-theme='light'] :focus-visible { + outline-color: var(--color-accent-500); +} + +/* ── Reduced motion ─────────────────────────────────────────────── */ + +@media (prefers-reduced-motion: reduce) { + nav.sidebar details > ul, + nav.sidebar details > summary svg, + site-search dialog, + site-search dialog::backdrop, + .toc-path-active, + .code-copy-btn, + .feedback-btn, + starlight-toc a { + transition-duration: 0s !important; + animation-duration: 0s !important; + } + + ::view-transition-old(main-content), + ::view-transition-new(main-content) { + animation-duration: 0s !important; + } +} diff --git a/docs/nx-cloudflare-docs/src/styles/custom.css b/docs/nx-cloudflare-docs/src/styles/custom.css new file mode 100644 index 000000000..92eddd81d --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/custom.css @@ -0,0 +1,307 @@ +@layer base, starlight, theme, components, utilities; + +@import '@astrojs/starlight-tailwind'; +@import 'tailwindcss/theme.css' layer(theme); +@import 'tailwindcss/utilities.css' layer(utilities); + +@import './theme-vars.css'; +@import './code-blocks.css'; +@import './sidebar.css'; +@import './layout.css'; +@import './toc.css'; +@import './components.css'; + +@theme { + /* ── Breakpoint: matches Starlight's mobile/desktop split ────────── */ + --breakpoint-desktop: 50rem; + + /* ── Typography ──────────────────────────────────────────────────── */ + /* Body shares the heading face (Inter); aliased here so Astro registers Inter once */ + --font-body: var(--font-heading); + --font-sans: var(--font-body, 'Inter'), 'SF Pro Display', -apple-system, + BlinkMacSystemFont, system-ui, sans-serif; + --font-mono: var(--font-code, 'JetBrains Mono'), 'SF Mono', 'Geist Mono', + ui-monospace, Menlo, monospace; + --font-display: var(--font-heading, 'Inter'), 'SF Pro Display', -apple-system, + system-ui, sans-serif; + + /* ── Accent: Cloudflare orange (#F38020) ────────────────────────── */ + --color-accent-50: #fff4ed; + --color-accent-100: #ffe6d5; + --color-accent-200: #fecfa8; + --color-accent-300: #fdb573; + --color-accent-400: #fb923c; + --color-accent-500: #f38020; + --color-accent-600: #d96d15; + --color-accent-700: #b35811; + --color-accent-800: #8f4815; + --color-accent-900: #723d18; + --color-accent-950: #42200b; + + /* ── Gray: Ocean-tinted navy scale (anchored to text hierarchy) ──── */ + --color-gray-50: #e7ecf3; + --color-gray-100: #c4d4e4; + --color-gray-200: #a8bbd0; + --color-gray-300: #9aa3b2; + --color-gray-400: #7a8a9c; + --color-gray-500: #5e6675; + --color-gray-600: #1a3a55; + --color-gray-700: #0f2b4a; + --color-gray-800: #0b0e16; + --color-gray-900: #07090f; + --color-gray-950: #04060b; + + /* ── Border radius tokens ───────────────────────────────────────── */ + --r-sm: 8px; + --r-md: 12px; + --r-lg: 18px; + --r-xl: 28px; +} + +/* ── Base content styling ──────────────────────────────────────────── */ + +/* Headings use Inter */ +.sl-markdown-content :is(h1, h2, h3, h4, h5, h6), +starlight-toc h2 { + font-family: var(--font-display); +} + +/* Content width and spacing */ +:root { + --sl-content-width: 52rem; + --sl-content-pad-x: 2rem; +} + +/* Thin scrollbar on content area */ +html { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-idle) transparent; + font-feature-settings: 'ss01', 'ss02', 'cv11'; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; +} + +html:hover { + scrollbar-color: var(--scrollbar-hover) transparent; +} + +/* ── Noise texture overlay ─────────────────────────────────────────── */ +.main-frame::before { + content: ''; + position: fixed; + inset: 0; + z-index: 100; + pointer-events: none; + opacity: 0.035; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); + background-repeat: repeat; + background-size: 256px; +} + +:root[data-theme='light'] .main-frame::before { + opacity: 0.02; +} + +/* h2 gradient bottom border */ +.sl-markdown-content h2 { + border-bottom: 1px solid transparent; + border-image: linear-gradient( + 90deg, + color-mix(in srgb, var(--color-accent-500) 30%, transparent), + rgba(250, 174, 64, 0.15), + transparent + ) + 1; + padding-bottom: 0.5rem; +} + +:root[data-theme='light'] .sl-markdown-content h2 { + border-image: linear-gradient( + 90deg, + color-mix(in srgb, var(--color-accent-500) 20%, transparent), + rgba(250, 174, 64, 0.08), + transparent + ) + 1; +} + +/* ── Landing page components ───────────────────────────────────────── */ + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin: 3rem 0; +} + +:root[data-theme='dark'] .feature-item { + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +:root[data-theme='light'] .feature-item { + background: rgba(10, 30, 53, 0.03); + border: 1px solid rgba(10, 30, 53, 0.08); +} + +.feature-item { + border-radius: 12px; + padding: 1.5rem; + transition: all 0.3s ease; + text-align: center; +} + +:root[data-theme='dark'] .feature-item:hover { + background: rgba(255, 255, 255, 0.08); +} + +:root[data-theme='light'] .feature-item:hover { + background: rgba(10, 30, 53, 0.06); +} + +.feature-icon { + font-size: 2.5rem; + margin-bottom: 1rem; + display: block; + transition: transform 0.3s ease; +} + +.feature-item:hover .feature-icon { + transform: scale(1.1) rotate(5deg); +} + +.feature-title { + font-weight: 600; + margin-bottom: 0.5rem; + color: var(--sl-color-text); + font-size: 1.1rem; +} + +.feature-description { + color: var(--sl-color-text-accent); + line-height: 1.6; + font-size: 0.95rem; +} + +:root[data-theme='dark'] .stats-container { + background: linear-gradient( + 135deg, + rgba(243, 128, 32, 0.1) 0%, + rgba(250, 174, 64, 0.1) 100% + ); + border: 1px solid rgba(255, 255, 255, 0.1); +} + +:root[data-theme='light'] .stats-container { + background: linear-gradient( + 135deg, + rgba(243, 128, 32, 0.08) 0%, + rgba(250, 174, 64, 0.08) 100% + ); + border: 1px solid rgba(10, 30, 53, 0.08); +} + +.stats-container { + border-radius: 16px; + padding: 3rem; + margin: 4rem 0; + text-align: center; +} + +.stats-container h2 { + margin-bottom: 1rem; + background: linear-gradient( + 135deg, + var(--color-accent-500) 0%, + var(--color-accent-400) 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + font-weight: 700; +} + +.action-buttons { + display: flex; + gap: 1rem; + justify-content: center; + margin: 2rem 0 0 0; + position: relative; + z-index: 1; +} + +.action-button { + padding: 0.75rem 1.5rem; + border-radius: 8px; + text-decoration: none; + font-weight: 600; + transition: all 0.3s ease; + display: inline-flex; + align-items: center; + gap: 0.5rem; + font-size: 0.9rem; + border: none; + cursor: pointer; +} + +.action-button.primary { + background: linear-gradient( + 135deg, + var(--color-accent-500) 0%, + var(--color-accent-400) 100% + ); + color: white; +} + +:root[data-theme='dark'] .action-button.secondary { + background: rgba(255, 255, 255, 0.1); + color: var(--sl-color-text); + border: 1px solid rgba(255, 255, 255, 0.2); +} + +:root[data-theme='light'] .action-button.secondary { + background: rgba(10, 30, 53, 0.05); + color: var(--sl-color-text); + border: 1px solid rgba(10, 30, 53, 0.12); +} + +.action-button:hover { + transform: translateY(-2px); + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); +} + +.action-button.primary:hover { + background: linear-gradient( + 135deg, + var(--color-accent-600) 0%, + var(--color-accent-500) 100% + ); +} + +@media (max-width: 49.9999rem) { + .stats-container { + padding: 2rem; + } + + .features-grid { + grid-template-columns: 1fr; + gap: 1.5rem; + } + + .action-buttons { + flex-direction: column; + align-items: center; + gap: 0.75rem; + } + + .action-button { + padding: 0.875rem 2rem; + width: 100%; + max-width: 250px; + justify-content: center; + } + + .feature-icon { + font-size: 2rem; + } +} diff --git a/docs/nx-cloudflare-docs/src/styles/layout.css b/docs/nx-cloudflare-docs/src/styles/layout.css new file mode 100644 index 000000000..0f37bf852 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/layout.css @@ -0,0 +1,68 @@ +/* ── Layout: desktop/mobile header & view transitions ────────────── */ + +/* Hide header on desktop (Fumadocs pattern) */ +@media (min-width: 50rem) { + :root { + --sl-nav-height: 0rem; + } + + .page > .header { + display: none; + } + + .sidebar-pane { + inset-block-start: 0; + } + + .main-frame { + padding-top: 0; + } +} + +/* Thin mobile header */ +@media (max-width: 49.9999rem) { + :root { + --sl-nav-height: 2.5rem; + } + + .page > .header { + background-color: var(--sl-color-bg-nav); + border-bottom: 1px solid + var(--sl-color-hairline-shade, rgba(255, 255, 255, 0.06)); + } + + :root[data-theme='light'] .page > .header { + background-color: #f5f0eb; + border-bottom: 1px solid rgba(10, 30, 53, 0.08); + } +} + +/* Mobile ToC bar */ +:root[data-theme='dark'] starlight-toc mobile-starlight-toc { + background-color: #07090f; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +/* Content area background — descending gradient */ +:root[data-theme='dark'] .main-frame { + background: linear-gradient(180deg, #0b0e16 0%, #04060b 40%); +} + +/* ── View Transitions ────────────────────────────────────────────── */ +/* Prevent sidebar flash during client-side navigation by isolating + main content and sidebar into their own transition groups. */ + +.main-frame { + view-transition-name: main-content; +} + +.sidebar-pane { + view-transition-name: sidebar; +} + +::view-transition-old(main-content), +::view-transition-new(main-content), +::view-transition-old(sidebar), +::view-transition-new(sidebar) { + animation-duration: 0s; +} diff --git a/docs/nx-cloudflare-docs/src/styles/sidebar.css b/docs/nx-cloudflare-docs/src/styles/sidebar.css new file mode 100644 index 000000000..bf2b3594f --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/sidebar.css @@ -0,0 +1,139 @@ +/* ── Sidebar: contrast, active states & layout ─────────────────── */ + +/* Section group headers — kicker style */ +nav.sidebar .top-level > li > details > summary, +nav.sidebar .top-level > li > a.large { + font-family: var(--font-mono); + font-size: 0.7rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.1em; +} + +:root[data-theme='dark'] nav.sidebar .top-level > li > details > summary, +:root[data-theme='dark'] nav.sidebar .top-level > li > a.large { + color: #e0f0ff; +} + +:root[data-theme='light'] nav.sidebar .top-level > li > details > summary, +:root[data-theme='light'] nav.sidebar .top-level > li > a.large { + color: #0a1e35; +} + +/* Sidebar links — dark mode */ +:root[data-theme='dark'] nav.sidebar a:not(.sidebar-logo) { + color: #7a9ab5; + transition: color 0.15s, background-color 0.15s; +} + +:root[data-theme='dark'] nav.sidebar a:not(.sidebar-logo):hover { + color: #c4d4e4; + background-color: color-mix(in srgb, var(--color-accent-500) 4%, transparent); +} + +:root[data-theme='dark'] nav.sidebar a[aria-current='page'] { + color: #e0f0ff; + background-color: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border-inline-start: 2px solid var(--color-accent-500); + font-weight: 500; +} + +/* Sidebar links — light mode */ +:root[data-theme='light'] nav.sidebar a:not(.sidebar-logo) { + color: #4a6a85; +} + +:root[data-theme='light'] nav.sidebar a:not(.sidebar-logo):hover { + color: #0a1e35; + background-color: color-mix(in srgb, var(--color-accent-500) 4%, transparent); +} + +:root[data-theme='light'] nav.sidebar a[aria-current='page'] { + color: #0a1e35; + background-color: color-mix(in srgb, var(--color-accent-500) 8%, transparent); + border-inline-start: 2px solid var(--color-accent-500); + font-weight: 500; +} + +/* Sidebar border & background */ +:root[data-theme='dark'] .sidebar-pane { + background-color: #07090f; + border-inline-end-color: rgba(255, 255, 255, 0.06); +} + +:root[data-theme='light'] .sidebar-pane { + background-color: #f5f0eb; + border-inline-end-color: rgba(10, 30, 53, 0.08); +} + +/* ── Sidebar layout: fixed top/bottom, scrollable nav ──────────── + These override Starlight's default sidebar layout to support a + fixed chrome area at top and bottom with a scrollable nav in + between. The !important declarations are necessary because + Starlight applies inline-level specificity on these elements. */ + +.sidebar-content { + display: flex !important; + flex-direction: column !important; + height: 100% !important; + min-height: 0 !important; +} + +.sidebar-content sl-sidebar-state-persist { + display: block !important; + flex: 1 1 0% !important; + min-height: 0 !important; + overflow-y: auto !important; +} + +.sidebar-bottom { + flex-shrink: 0; +} + +@media (min-width: 50rem) { + .sidebar-pane { + overflow: hidden !important; + } + + .sidebar-content { + overflow: hidden !important; + } + + .sidebar-content sl-sidebar-state-persist { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-idle) transparent; + } + + .sidebar-content sl-sidebar-state-persist:hover { + scrollbar-color: var(--scrollbar-hover) transparent; + } + + .sidebar-chrome { + flex-shrink: 0; + } +} + +/* ── Sidebar animations ──────────────────────────────────────────── */ + +nav.sidebar details > ul { + overflow: hidden; + transition: max-height 0.25s ease-out, opacity 0.2s ease-out; +} + +nav.sidebar details:not([open]) > ul { + max-height: 0; + opacity: 0; +} + +nav.sidebar details[open] > ul { + max-height: 100vh; + opacity: 1; +} + +nav.sidebar details > summary svg { + transition: transform 0.2s ease-out; +} + +nav.sidebar details[open] > summary svg { + transform: rotate(90deg); +} diff --git a/docs/nx-cloudflare-docs/src/styles/theme-vars.css b/docs/nx-cloudflare-docs/src/styles/theme-vars.css new file mode 100644 index 000000000..af26f1000 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/theme-vars.css @@ -0,0 +1,49 @@ +/* ── Theme custom properties ─────────────────────────────────────── */ +/* Dark/light Starlight overrides + pagefind + scrollbar colors */ + +:root[data-theme='dark'] { + --sl-color-bg: #04060b; + --sl-color-text-accent: var(--color-accent-500); + --sl-color-bg-sidebar: #07090f; + --sl-color-backdrop-overlay: rgba(4, 6, 11, 0.8); + --sl-color-bg-nav: #07090f; + --pagefind-ui-primary: var(--color-accent-500); + --pagefind-ui-text: #e0f0ff; + --pagefind-ui-background: #0b0e16; + --pagefind-ui-border: rgba(255, 255, 255, 0.1); + --pagefind-ui-tag: color-mix( + in srgb, + var(--color-accent-500) 10%, + transparent + ); + --scrollbar-idle: rgba(255, 255, 255, 0.08); + --scrollbar-hover: rgba(255, 255, 255, 0.15); +} + +:root[data-theme='light'] { + --sl-color-bg: #fefaf5; + --sl-color-text-accent: var(--color-accent-500); + --sl-color-bg-sidebar: #f5f0eb; + --sl-color-bg-nav: #f5f0eb; + --sl-color-hairline-shade: rgba(10, 30, 53, 0.08); + --sl-color-white: #0a1e35; + --sl-color-black: #fefaf5; + --sl-color-text: #1a3a55; + --sl-color-gray-1: #2a4a65; + --sl-color-gray-2: #3a5a75; + --sl-color-gray-3: #5a7a95; + --sl-color-gray-4: #9ab4cc; + --sl-color-gray-5: #d4dce4; + --sl-color-gray-6: #eae4dc; + --pagefind-ui-primary: var(--color-accent-500); + --pagefind-ui-text: #0a1e35; + --pagefind-ui-background: #fefcf8; + --pagefind-ui-border: rgba(10, 30, 53, 0.1); + --pagefind-ui-tag: color-mix( + in srgb, + var(--color-accent-500) 8%, + transparent + ); + --scrollbar-idle: rgba(10, 30, 53, 0.08); + --scrollbar-hover: rgba(10, 30, 53, 0.15); +} diff --git a/docs/nx-cloudflare-docs/src/styles/toc.css b/docs/nx-cloudflare-docs/src/styles/toc.css new file mode 100644 index 000000000..844a45605 --- /dev/null +++ b/docs/nx-cloudflare-docs/src/styles/toc.css @@ -0,0 +1,67 @@ +/* ── Table of Contents: active indicator (Fumadocs-style) ──────── */ + +starlight-toc nav ul { + padding-inline-start: 1rem; +} + +starlight-toc a { + position: relative; + transition: color 0.15s; +} + +/* Neutralize Starlight's aria-current styling — our scroll-based + tracking (toc-path.ts) uses .toc-active instead. !important is + required because Starlight sets aria-current via its own + IntersectionObserver independently of our scroll tracking. */ +starlight-toc a[aria-current='true'] { + color: inherit !important; +} + +:root[data-theme='dark'] starlight-toc a.toc-active { + color: var(--color-accent-500) !important; +} + +:root[data-theme='light'] starlight-toc a.toc-active { + color: var(--color-accent-500) !important; +} + +/* Wrapper for SVG path (created by toc-path.ts) */ +.toc-items-wrapper { + position: relative; +} + +.toc-path-svg { + position: absolute; + inset-inline-start: 0; + top: 0; + pointer-events: none; +} + +.toc-path-bg { + fill: none; + stroke: rgba(255, 255, 255, 0.08); + stroke-width: 1.5; + stroke-linecap: round; +} + +.toc-path-active { + fill: none; + stroke: var(--color-accent-500); + stroke-width: 1.5; + stroke-linecap: round; + filter: drop-shadow( + 0 0 3px color-mix(in srgb, var(--color-accent-500) 40%, transparent) + ); + transition: clip-path 0.25s ease; +} + +:root[data-theme='light'] .toc-path-bg { + stroke: rgba(10, 30, 53, 0.1); +} + +:root[data-theme='light'] .toc-path-active { + stroke: var(--color-accent-500); + filter: drop-shadow( + 0 0 3px color-mix(in srgb, var(--color-accent-500) 25%, transparent) + ); +} diff --git a/docs/nx-cloudflare-docs/tsconfig.json b/docs/nx-cloudflare-docs/tsconfig.json new file mode 100644 index 000000000..79ac97a6b --- /dev/null +++ b/docs/nx-cloudflare-docs/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "astro/tsconfigs/strict", + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "react" + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.astro", + "astro.config.mjs" + ], + "exclude": ["dist", "node_modules"] +} diff --git a/docs/nx-cloudflare-docs/wrangler.jsonc b/docs/nx-cloudflare-docs/wrangler.jsonc new file mode 100644 index 000000000..1eca2ea1f --- /dev/null +++ b/docs/nx-cloudflare-docs/wrangler.jsonc @@ -0,0 +1,19 @@ +{ + "$schema": "../../node_modules/wrangler/config-schema.json", + "name": "nx-cloudflare-docs", + "compatibility_date": "2025-06-21", + "assets": { + "directory": "../../dist/docs/nx-cloudflare-docs/", + "not_found_handling": "404-page" + }, + "observability": { + "enabled": true, + "head_sampling_rate": 1, + "logs": { + "enabled": true, + "head_sampling_rate": 1, + "persist": true, + "invocation_logs": true + } + } +} diff --git a/package.json b/package.json index 968340707..cbf8f4069 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,11 @@ ], "catalog": { "@angular-devkit/core": "~17.3.7", - "@astrojs/starlight": "^0.35.1", + "@astrojs/react": "^5.0.1", + "@astrojs/sitemap": "^3.7.1", + "@astrojs/starlight": "^0.39.0", + "@astrojs/starlight-tailwind": "^5.0.0", + "@tailwindcss/vite": "^4.2.2", "@cloudflare/vitest-pool-workers": "^0.12.0", "@cloudflare/workers-types": "^4.20250404.0", "@commitlint/cli": "^17.8.1", @@ -48,7 +52,7 @@ "@typescript-eslint/parser": "7.18.0", "@vitest/coverage-v8": "4.0.9", "@vitest/ui": "4.0.9", - "astro": "^5.6.1", + "astro": "^6.1.0", "chalk": "^4.1.2", "cli-spinners": "^2.9.2", "dotenv": "^16.4.4", @@ -76,20 +80,29 @@ "sharp": "^0.34.2", "strip-indent": "^3.0.0", "tcp-port-used": "^1.0.2", + "starlight-llms-txt": "^0.8.0", + "starlight-typedoc": "^0.22.0", + "tailwindcss": "^4.2.2", "tree-kill": "^1.2.2", "tree-sitter-go": "^0.25.0", "ts-node": "10.9.1", "tslib": "^2.3.0", + "typedoc": "^0.28.0", + "typedoc-plugin-markdown": "^4.6.0", "tsx": "^4.19.4", "typescript": "5.9.3", "verdaccio": "6.7.2", - "vite": "8.0.9", + "vite": "^7.3.2", "vitest": "4.0.9", "web-tree-sitter": "0.26.3", "wrangler": "^4.26.0" }, "devDependencies": { "@angular-devkit/core": "catalog:", + "@astrojs/react": "catalog:", + "@astrojs/sitemap": "catalog:", + "@astrojs/starlight": "catalog:", + "@astrojs/starlight-tailwind": "catalog:", "@cloudflare/vitest-pool-workers": "catalog:", "@cloudflare/workers-types": "catalog:", "@commitlint/cli": "catalog:", @@ -114,8 +127,10 @@ "@swc/cli": "catalog:", "@swc/core": "catalog:", "@swc/helpers": "catalog:", + "@tailwindcss/vite": "catalog:", "@testing-library/react": "catalog:", "@types/bun": "catalog:", + "@types/fs-extra": "catalog:", "@types/kill-port": "catalog:", "@types/node": "catalog:", "@types/react": "catalog:", @@ -147,11 +162,17 @@ "p-limit": "catalog:", "prettier": "catalog:", "semver": "catalog:", + "starlight-llms-txt": "catalog:", + "starlight-typedoc": "catalog:", "strip-indent": "catalog:", "tcp-port-used": "catalog:", + "tailwindcss": "catalog:", "tree-kill": "catalog:", "tree-sitter-go": "catalog:", "ts-node": "catalog:", + "tslib": "catalog:", + "typedoc": "catalog:", + "typedoc-plugin-markdown": "catalog:", "tsx": "catalog:", "typescript": "catalog:", "verdaccio": "catalog:", @@ -161,14 +182,22 @@ "wrangler": "catalog:" }, "dependencies": { + "@astrojs/react": "catalog:", + "@astrojs/sitemap": "catalog:", "@astrojs/starlight": "catalog:", - "@types/fs-extra": "catalog:", + "@astrojs/starlight-tailwind": "catalog:", + "@tailwindcss/vite": "catalog:", "astro": "catalog:", "hono": "catalog:", "react": "catalog:", "react-dom": "catalog:", "sharp": "catalog:", - "tslib": "catalog:" + "starlight-llms-txt": "catalog:", + "starlight-typedoc": "catalog:", + "tailwindcss": "catalog:", + "tslib": "catalog:", + "typedoc": "catalog:", + "typedoc-plugin-markdown": "catalog:" }, "nx": { "includedScripts": [], diff --git a/packages/gonx/README.md b/packages/gonx/README.md index 70b877b27..492b461cd 100644 --- a/packages/gonx/README.md +++ b/packages/gonx/README.md @@ -11,7 +11,7 @@ [![commitizen](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)]() [![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)]() [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) -[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-) @@ -24,7 +24,7 @@ - Well-structured Go code scaffolding - Generate Go Libraries - Full Nx integration - - Inferred Tasks: Build, Generate, Tidy, Test, Run, and Lint + - Inferred Tasks: Build, Generate, Tidy, Test, Serve, and Lint - Cacheable Tasks: Build, Generate, Tidy, Test, and Lint - GraphV2 Support - Version Actions for Go release @@ -50,28 +50,6 @@ npx create-nx-workspace go-workspace --preset=@naxodev/gonx nx add @naxodev/gonx ``` -## Plugin Options - -Configure the plugin in your `nx.json`: - -```json -{ - "plugins": [ - { - "plugin": "@naxodev/gonx", - "options": {} - } - ] -} -``` - -| Option | Type | Default | Description | -| ----------------------- | ------- | ------- | ------------------------------------- | -| `skipGoDependencyCheck` | boolean | `false` | Disable dependency detection entirely | - -See [Dependency Detection](./docs/static-analysis.md) for details on -how dependencies between Go projects are resolved. - ## Docs To read the full documentation, check out the diff --git a/packages/gonx/src/release/go-version-actions.spec.ts b/packages/gonx/src/release/go-version-actions.spec.ts new file mode 100644 index 000000000..f92a3eb4d --- /dev/null +++ b/packages/gonx/src/release/go-version-actions.spec.ts @@ -0,0 +1,45 @@ +import { describe, it, expect } from 'bun:test'; +import type { ProjectGraph, Tree } from '@nx/devkit'; +import GoVersionActions from './go-version-actions'; + +// Minimal construction helper. The constructor performs no side effects — it +// only assigns fields; the side-effecting `init(tree)` is never called here — +// and the behavior under test reads none of those fields, so empty stubs are +// sufficient to exercise the public method. +function createActions(): GoVersionActions { + return new GoVersionActions( + {} as ConstructorParameters[0], + { + name: 'proj-b', + type: 'lib', + data: { root: 'libs/proj-b' }, + } as ConstructorParameters[1], + {} as ConstructorParameters[2] + ); +} + +describe('GoVersionActions', () => { + describe('readCurrentVersionOfDependency', () => { + // Reproduces #91: nx release on a Go release group fails because this method + // threw "Method not implemented". Go resolves local (workspace) dependencies + // by path, never by a version spec in go.mod, so there is no dependency + // version to read — we must report null rather than throw, which tells + // nx release there is no dependency version spec to update. + it('reports no applicable dependency version instead of throwing', async () => { + const actions = createActions(); + + // `.resolves` (not a bare await) makes the regression explicit: before + // #91 this rejected with "Method not implemented", aborting nx release. + await expect( + actions.readCurrentVersionOfDependency( + {} as Tree, + {} as ProjectGraph, + 'proj-a' + ) + ).resolves.toEqual({ + currentVersion: null, + dependencyCollection: null, + }); + }); + }); +}); diff --git a/packages/gonx/src/release/go-version-actions.ts b/packages/gonx/src/release/go-version-actions.ts index dca07594e..fdeb0cd31 100644 --- a/packages/gonx/src/release/go-version-actions.ts +++ b/packages/gonx/src/release/go-version-actions.ts @@ -75,8 +75,12 @@ export default class GoVersionActions extends VersionActions { } } - // For local dependencies, Go ignores the version specified in the module and always uses the one in the local path. - readCurrentVersionOfDependency( + // For local dependencies, Go resolves the module from the local path (via a + // go.work workspace or a `replace` directive), never from a version spec in + // go.mod. There is therefore no dependency version to read, so we report null + // — signalling nx release that there is no dependency version spec to update, + // which lets release groups of interdependent Go projects version cleanly. + async readCurrentVersionOfDependency( tree: Tree, projectGraph: ProjectGraph, dependencyProjectName: string @@ -84,7 +88,10 @@ export default class GoVersionActions extends VersionActions { currentVersion: string | null; dependencyCollection: string | null; }> { - throw new Error('Method not implemented.'); + return { + currentVersion: null, + dependencyCollection: null, + }; } // Since go.mod does not contain the version, we cannot update it. diff --git a/packages/nx-cloudflare/README.md b/packages/nx-cloudflare/README.md index 2742dbb13..a69dadea8 100644 --- a/packages/nx-cloudflare/README.md +++ b/packages/nx-cloudflare/README.md @@ -11,36 +11,37 @@ [![commitizen](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)]() [![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)]() [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) -[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
-Nx plugin for Cloudflare. +Nx plugin for [Cloudflare Workers](https://developers.cloudflare.com/workers/). It wraps the [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/) for target inference and uses [create-cloudflare (C3)](https://developers.cloudflare.com/workers/get-started/create-worker/) for project scaffolding. ## Features -- ✅ Generate Cloudflare Worker Application - - ✅ Include Fetch Handler template - - ✅ Include Scheduled Handler template - - ✅ Vitest tests support - - ✅ Inferred `serve`, `deploy`, `typegen`, `version-upload`, and `tail` targets (via the `@naxodev/nx-cloudflare/plugin` Crystal plugin). -- ✅ Generate Cloudflare Worker Library +- Scaffold Cloudflare Worker applications via create-cloudflare (C3) — Worker templates, web frameworks, or remote git templates. +- Generate Cloudflare Worker libraries (publishable, with bundler/linter/test options). +- Inferred `serve`, `deploy`, `typegen`, `version-upload`, and `tail` targets via the `@naxodev/nx-cloudflare/plugin` inference plugin — no hand-written `project.json` targets. +- Customizable inferred target names via `CloudflarePluginOptions`. +- Vitest wired automatically when the C3 template ships a Vitest config. -## Installation +## Getting started -Nx Cloudflare is published as the `@naxodev/nx-cloudflare` package. +### Add to an existing workspace -| Toolchain | Command | -| --------- | ------------------------------------ | -| NPM CLI | `npm install @naxodev/nx-cloudflare` | -| PNPM CLI | `pnpm add @naxodev/nx-cloudflare` | -| Yarn CLI | `yarn add @naxodev/nx-cloudflare` | +```shell +nx add @naxodev/nx-cloudflare +``` -## Compatibility +### Generate a Cloudflare Worker -Nx Cloudflare is compatible with the following versions of Nx: +```shell +nx g @naxodev/nx-cloudflare:application my-worker +``` + +## Compatibility | Nx Version | Nx Cloudflare Version | | ---------- | --------------------- | @@ -49,110 +50,14 @@ Nx Cloudflare is compatible with the following versions of Nx: | 19.x | 3.x | | 20.x | 4.x | | 21.x | 5.x | +| 22–23.x | 6.x | -## Usage - -### Cloudflare Worker Application - -#### Generating a new Cloudflare Worker Application - -```bash -nx g @naxodev/nx-cloudflare:application my-worker-app -``` - -Available options: - -| Option | Type | Default | Description | -| ------------------------ | -------------------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | string | \*required | What name would you like to use? | -| template | fetch-handler, scheduled-handler, hono, none | fetch-handler | Which worker template do you want to use? | -| projectNameAndRootFormat | as-provided, derived | as-provided | Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`). | -| port | number | 8787 | The port in which the worker will be run on development mode | -| accountId | string | null | The Cloudflare account identifier where the worker will be deployed | -| configFormat | jsonc, toml | jsonc | Format of the generated Wrangler configuration file (`wrangler.jsonc` or `wrangler.toml`). | -| js | boolean | false | Use JavaScript instead of TypeScript | -| tags | string | null | Add tags to the application (used for linting). | -| unitTestRunner | vitest, none | vitest | Test runner to use for unit tests. | -| directory | string | null | The directory of the new application. | -| rootProject | boolean | false | Create worker application at the root of the workspace | -| skipFormat | boolean | false | Skip formatting files. | - -##### Wrangler configuration format - -The generator emits a [`wrangler.jsonc`](https://developers.cloudflare.com/workers/wrangler/configuration/) by default — Cloudflare's recommended format, and the only one that some newer Wrangler features support. The generated file includes a `$schema` reference (resolved relative to the workspace-root `node_modules`) so editors validate and autocomplete the config: - -```jsonc -{ - "$schema": "../node_modules/wrangler/config-schema.json", - "name": "my-worker-app", - "compatibility_date": "2026-06-05", - "compatibility_flags": ["nodejs_compat"], - "main": "src/index.ts" -} -``` - -To generate a `wrangler.toml` instead, pass `--configFormat=toml`: - -```bash -nx g @naxodev/nx-cloudflare:application my-worker-app --configFormat=toml -``` +Wrangler v4 is a required peer dependency. -#### Inferred targets - -Generated Worker projects get their targets from the `@naxodev/nx-cloudflare/plugin` inference plugin (registered in `nx.json` by the generator). Any project with a `wrangler.{jsonc,toml,json}` beside a `project.json`/`package.json` gets: - -| Target | Runs | Notes | -| ---------------- | -------------------------- | -------------------------------------- | -| `serve` | `wrangler dev` | Continuous local dev server. | -| `deploy` | `wrangler deploy` | Deploys the Worker. | -| `typegen` | `wrangler types` | Generates `worker-configuration.d.ts`. | -| `version-upload` | `wrangler versions upload` | Uploads a version (gradual deploys). | -| `tail` | `wrangler tail` | Streams live logs. | - -```bash -nx serve -nx deploy -``` - -These targets wrap the Wrangler CLI, so any Wrangler flag passes straight through after `--`: - -```bash -nx serve -- --remote -nx deploy -- --dry-run -``` - -See the [`wrangler dev`](https://developers.cloudflare.com/workers/wrangler/commands/#dev) and [`wrangler deploy`](https://developers.cloudflare.com/workers/wrangler/commands/#deploy) docs for the full flag list. The dev-server port is set via `dev.port` in the generated `wrangler` config (defaults to `8787`). - -`worker-configuration.d.ts` (your typed `Env` and runtime types) is the `typegen` target's declared output, so it is treated as a generated build artifact — the generator git-ignores it instead of committing it. Run `nx typegen ` to (re)generate it, and re-run after changing bindings or `compatibility_date` in your `wrangler` config. - -### Cloudflare Worker Library - -#### Generating a new Cloudflare Worker Library - -```bash -nx g @naxodev/nx-cloudflare:library my-worker-lib -``` +## Docs -Available options: - -| Option | Type | Default | Description | -| ------------------------ | ----------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | string | \*required | What name would you like to use? | -| directory | string | null | The directory of the new application. | -| projectNameAndRootFormat | as-provided, derived | as-provided | Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`). | -| linter | eslint, none | eslint | The tool to use for running lint checks. | -| unitTestRunner | vitest, none | vitest | Test runner to use for unit tests. | -| tags | string | null | Add tags to the application (used for linting). | -| skipFormat | boolean | false | Skip formatting files. | -| js | boolean | false | Use JavaScript instead of TypeScript | -| strict | boolean | true | Whether to enable tsconfig strict mode or not. | -| publishable | boolean | false | Generate a publishable library. | -| importPath | string | null | The library name used to import it, like @myorg/my-awesome-lib. Required for publishable library. | -| bundler | swc, tsc, vite, esbuild, none | tsc | Which bundler would you like to use to build the library? Choose 'none' to skip build setup. | -| minimal | boolean | false | Generate a library with a minimal setup. No README.md generated. | -| simpleName | boolean | false | Don't include the directory in the generated file name. | - -Worker libraries pull in Workers runtime types from `@cloudflare/workers-types` rather than a generated `worker-configuration.d.ts`. A library has no `wrangler` config of its own, so there are no bindings to type and nothing for `wrangler types` to generate — the `typegen` target is inferred only for Worker applications. +To read the full documentation, check out the +[docs](https://nx-cloudflare.naxo.dev/) site. ## Acknowledgement