polen 0.9.1-next.2 → 0.10.0-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -364
- package/build/api/api.d.ts +1 -0
- package/build/api/api.d.ts.map +1 -1
- package/build/api/api.js +1 -0
- package/build/api/api.js.map +1 -1
- package/build/api/config/configurator.d.ts +9 -1
- package/build/api/config/configurator.d.ts.map +1 -1
- package/build/api/config/configurator.js +18 -6
- package/build/api/config/configurator.js.map +1 -1
- package/build/api/config/load.js +5 -5
- package/build/api/config/load.js.map +1 -1
- package/build/api/config-resolver/resolve.js +2 -2
- package/build/api/config-resolver/resolve.js.map +1 -1
- package/build/api/content/$$.d.ts +7 -0
- package/build/api/content/$$.d.ts.map +1 -0
- package/build/api/content/$$.js +7 -0
- package/build/api/content/$$.js.map +1 -0
- package/build/api/content/$.d.ts +2 -0
- package/build/api/content/$.d.ts.map +1 -0
- package/build/api/content/$.js +2 -0
- package/build/api/content/$.js.map +1 -0
- package/build/api/content/metadata.d.ts +10 -0
- package/build/api/content/metadata.d.ts.map +1 -0
- package/build/api/content/metadata.js +9 -0
- package/build/api/content/metadata.js.map +1 -0
- package/build/api/content/navbar.d.ts +10 -0
- package/build/api/content/navbar.d.ts.map +1 -0
- package/build/api/content/navbar.js +45 -0
- package/build/api/content/navbar.js.map +1 -0
- package/build/api/content/page.d.ts +11 -0
- package/build/api/content/page.d.ts.map +1 -0
- package/build/api/content/page.js +2 -0
- package/build/api/content/page.js.map +1 -0
- package/build/api/content/scan.d.ts +19 -0
- package/build/api/content/scan.d.ts.map +1 -0
- package/build/api/content/scan.js +90 -0
- package/build/api/content/scan.js.map +1 -0
- package/build/api/content/sidebar.d.ts +104 -0
- package/build/api/content/sidebar.d.ts.map +1 -0
- package/build/api/content/sidebar.js +166 -0
- package/build/api/content/sidebar.js.map +1 -0
- package/build/api/content/utils.d.ts +5 -0
- package/build/api/content/utils.d.ts.map +1 -0
- package/build/api/content/utils.js +8 -0
- package/build/api/content/utils.js.map +1 -0
- package/build/api/schema/data-sources/schema-directory/schema-directory.js +1 -1
- package/build/api/schema/data-sources/schema-directory/schema-directory.js.map +1 -1
- package/build/api/static/index.d.ts +2 -0
- package/build/api/static/index.d.ts.map +1 -0
- package/build/api/static/index.js +2 -0
- package/build/api/static/index.js.map +1 -0
- package/build/api/static/manifest.d.ts +18 -0
- package/build/api/static/manifest.d.ts.map +1 -0
- package/build/api/static/manifest.js +13 -0
- package/build/api/static/manifest.js.map +1 -0
- package/build/api/static/rebase.d.ts +14 -0
- package/build/api/static/rebase.d.ts.map +1 -0
- package/build/api/static/rebase.js +110 -0
- package/build/api/static/rebase.js.map +1 -0
- package/build/api/static/static.d.ts +3 -0
- package/build/api/static/static.d.ts.map +1 -0
- package/build/api/static/static.js +3 -0
- package/build/api/static/static.js.map +1 -0
- package/build/api/vite/plugins/branding/index.d.ts +4 -0
- package/build/api/vite/plugins/branding/index.d.ts.map +1 -0
- package/build/api/vite/plugins/branding/index.js +80 -0
- package/build/api/vite/plugins/branding/index.js.map +1 -0
- package/build/api/vite/plugins/build.d.ts.map +1 -1
- package/build/api/vite/plugins/build.js +22 -1
- package/build/api/vite/plugins/build.js.map +1 -1
- package/build/api/vite/plugins/core.d.ts +2 -2
- package/build/api/vite/plugins/core.d.ts.map +1 -1
- package/build/api/vite/plugins/core.js +4 -5
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/api/vite/plugins/main.d.ts.map +1 -1
- package/build/api/vite/plugins/main.js +2 -1
- package/build/api/vite/plugins/main.js.map +1 -1
- package/build/api/vite/plugins/pages.d.ts +8 -14
- package/build/api/vite/plugins/pages.d.ts.map +1 -1
- package/build/api/vite/plugins/pages.js +110 -183
- package/build/api/vite/plugins/pages.js.map +1 -1
- package/build/api/vite/plugins/serve.js +5 -5
- package/build/api/vite/plugins/serve.js.map +1 -1
- package/build/cli/_/self-contained-mode.js +5 -5
- package/build/cli/_/self-contained-mode.js.map +1 -1
- package/build/cli/commands/static/$default.d.ts +3 -0
- package/build/cli/commands/static/$default.d.ts.map +1 -0
- package/build/cli/commands/static/$default.js +38 -0
- package/build/cli/commands/static/$default.js.map +1 -0
- package/build/cli/commands/static/rebase.d.ts +2 -0
- package/build/cli/commands/static/rebase.d.ts.map +1 -0
- package/build/cli/commands/static/rebase.js +26 -0
- package/build/cli/commands/static/rebase.js.map +1 -0
- package/build/cli/commands/static.d.ts +3 -0
- package/build/cli/commands/static.d.ts.map +1 -0
- package/build/cli/commands/static.js +5 -0
- package/build/cli/commands/static.js.map +1 -0
- package/build/exports/components.d.ts +2 -0
- package/build/exports/components.d.ts.map +1 -0
- package/build/exports/components.js +2 -0
- package/build/exports/components.js.map +1 -0
- package/build/lib/demos/builder.d.ts +83 -0
- package/build/lib/demos/builder.d.ts.map +1 -0
- package/build/lib/demos/builder.js +237 -0
- package/build/lib/demos/builder.js.map +1 -0
- package/build/lib/demos/config-schema.d.ts +243 -0
- package/build/lib/demos/config-schema.d.ts.map +1 -0
- package/build/lib/demos/config-schema.js +52 -0
- package/build/lib/demos/config-schema.js.map +1 -0
- package/build/lib/demos/config.d.ts +40 -0
- package/build/lib/demos/config.d.ts.map +1 -0
- package/build/lib/demos/config.js +180 -0
- package/build/lib/demos/config.js.map +1 -0
- package/build/lib/demos/index.d.ts +9 -0
- package/build/lib/demos/index.d.ts.map +1 -0
- package/build/lib/demos/index.js +8 -0
- package/build/lib/demos/index.js.map +1 -0
- package/build/lib/demos/ui/components.d.ts +33 -0
- package/build/lib/demos/ui/components.d.ts.map +1 -0
- package/build/lib/demos/ui/components.js +699 -0
- package/build/lib/demos/ui/components.js.map +1 -0
- package/build/lib/demos/ui/data-collector.d.ts +88 -0
- package/build/lib/demos/ui/data-collector.d.ts.map +1 -0
- package/build/lib/demos/ui/data-collector.js +174 -0
- package/build/lib/demos/ui/data-collector.js.map +1 -0
- package/build/lib/demos/ui/landing-page-cli.d.ts +3 -0
- package/build/lib/demos/ui/landing-page-cli.d.ts.map +1 -0
- package/build/lib/demos/ui/landing-page-cli.js +21 -0
- package/build/lib/demos/ui/landing-page-cli.js.map +1 -0
- package/build/lib/demos/ui/landing-page.d.ts +32 -0
- package/build/lib/demos/ui/landing-page.d.ts.map +1 -0
- package/build/lib/demos/ui/landing-page.js +83 -0
- package/build/lib/demos/ui/landing-page.js.map +1 -0
- package/build/lib/demos/ui/page-renderer.d.ts +26 -0
- package/build/lib/demos/ui/page-renderer.d.ts.map +1 -0
- package/build/lib/demos/ui/page-renderer.js +104 -0
- package/build/lib/demos/ui/page-renderer.js.map +1 -0
- package/build/lib/demos/utils.d.ts +14 -0
- package/build/lib/demos/utils.d.ts.map +1 -0
- package/build/lib/demos/utils.js +37 -0
- package/build/lib/demos/utils.js.map +1 -0
- package/build/lib/deployment/$$.d.ts +3 -0
- package/build/lib/deployment/$$.d.ts.map +1 -0
- package/build/lib/deployment/$$.js +3 -0
- package/build/lib/deployment/$$.js.map +1 -0
- package/build/lib/deployment/$.d.ts +2 -0
- package/build/lib/deployment/$.d.ts.map +1 -0
- package/build/lib/deployment/$.js +2 -0
- package/build/lib/deployment/$.js.map +1 -0
- package/build/lib/deployment/metadata.d.ts +32 -0
- package/build/lib/deployment/metadata.d.ts.map +1 -0
- package/build/lib/deployment/metadata.js +37 -0
- package/build/lib/deployment/metadata.js.map +1 -0
- package/build/lib/deployment/path-manager.d.ts +41 -0
- package/build/lib/deployment/path-manager.d.ts.map +1 -0
- package/build/lib/deployment/path-manager.js +157 -0
- package/build/lib/deployment/path-manager.js.map +1 -0
- package/build/lib/file-router/file-router.d.ts +0 -2
- package/build/lib/file-router/file-router.d.ts.map +1 -1
- package/build/lib/file-router/file-router.js +0 -2
- package/build/lib/file-router/file-router.js.map +1 -1
- package/build/lib/file-router/route.d.ts +2 -0
- package/build/lib/file-router/route.d.ts.map +1 -1
- package/build/lib/file-router/route.js.map +1 -1
- package/build/lib/file-router/scan.d.ts.map +1 -1
- package/build/lib/file-router/scan.js +22 -13
- package/build/lib/file-router/scan.js.map +1 -1
- package/build/lib/github-actions/git-controller.d.ts +50 -0
- package/build/lib/github-actions/git-controller.d.ts.map +1 -0
- package/build/lib/github-actions/git-controller.js +90 -0
- package/build/lib/github-actions/git-controller.js.map +1 -0
- package/build/lib/github-actions/github-actions.d.ts +7 -0
- package/build/lib/github-actions/github-actions.d.ts.map +1 -0
- package/build/lib/github-actions/github-actions.js +7 -0
- package/build/lib/github-actions/github-actions.js.map +1 -0
- package/build/lib/github-actions/index.d.ts +2 -0
- package/build/lib/github-actions/index.d.ts.map +1 -0
- package/build/lib/github-actions/index.js +2 -0
- package/build/lib/github-actions/index.js.map +1 -0
- package/build/lib/github-actions/lib/get-pr-deployments.d.ts +12 -0
- package/build/lib/github-actions/lib/get-pr-deployments.d.ts.map +1 -0
- package/build/lib/github-actions/lib/get-pr-deployments.js +51 -0
- package/build/lib/github-actions/lib/get-pr-deployments.js.map +1 -0
- package/build/lib/github-actions/pr-controller.d.ts +39 -0
- package/build/lib/github-actions/pr-controller.d.ts.map +1 -0
- package/build/lib/github-actions/pr-controller.js +122 -0
- package/build/lib/github-actions/pr-controller.js.map +1 -0
- package/build/lib/github-actions/run-step-cli.d.ts +9 -0
- package/build/lib/github-actions/run-step-cli.d.ts.map +1 -0
- package/build/lib/github-actions/run-step-cli.js +71 -0
- package/build/lib/github-actions/run-step-cli.js.map +1 -0
- package/build/lib/github-actions/runner.d.ts +17 -0
- package/build/lib/github-actions/runner.d.ts.map +1 -0
- package/build/lib/github-actions/runner.js +195 -0
- package/build/lib/github-actions/runner.js.map +1 -0
- package/build/lib/github-actions/schemas/context.d.ts +933 -0
- package/build/lib/github-actions/schemas/context.d.ts.map +1 -0
- package/build/lib/github-actions/schemas/context.js +407 -0
- package/build/lib/github-actions/schemas/context.js.map +1 -0
- package/build/lib/github-actions/schemas/index.d.ts +5 -0
- package/build/lib/github-actions/schemas/index.d.ts.map +1 -0
- package/build/lib/github-actions/schemas/index.js +5 -0
- package/build/lib/github-actions/schemas/index.js.map +1 -0
- package/build/lib/github-actions/search-module.d.ts +38 -0
- package/build/lib/github-actions/search-module.d.ts.map +1 -0
- package/build/lib/github-actions/search-module.js +40 -0
- package/build/lib/github-actions/search-module.js.map +1 -0
- package/build/lib/github-actions/step.d.ts +163 -0
- package/build/lib/github-actions/step.d.ts.map +1 -0
- package/build/lib/github-actions/step.js +121 -0
- package/build/lib/github-actions/step.js.map +1 -0
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +5 -3
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/kit-temp.d.ts +54 -0
- package/build/lib/kit-temp.d.ts.map +1 -1
- package/build/lib/kit-temp.js +82 -14
- package/build/lib/kit-temp.js.map +1 -1
- package/build/lib/kit-temp.test-d.d.ts +2 -0
- package/build/lib/kit-temp.test-d.d.ts.map +1 -0
- package/build/lib/kit-temp.test-d.js +75 -0
- package/build/lib/kit-temp.test-d.js.map +1 -0
- package/build/lib/mask/$$.d.ts +3 -0
- package/build/lib/mask/$$.d.ts.map +1 -0
- package/build/lib/mask/$$.js +3 -0
- package/build/lib/mask/$$.js.map +1 -0
- package/build/lib/mask/$.d.ts +2 -0
- package/build/lib/mask/$.d.ts.map +1 -0
- package/build/lib/mask/$.js +2 -0
- package/build/lib/mask/$.js.map +1 -0
- package/build/lib/mask/apply.d.ts +86 -0
- package/build/lib/mask/apply.d.ts.map +1 -0
- package/build/lib/mask/apply.js +86 -0
- package/build/lib/mask/apply.js.map +1 -0
- package/build/lib/mask/mask.d.ts +124 -0
- package/build/lib/mask/mask.d.ts.map +1 -0
- package/build/lib/mask/mask.js +137 -0
- package/build/lib/mask/mask.js.map +1 -0
- package/build/lib/mask/mask.test-d.d.ts +2 -0
- package/build/lib/mask/mask.test-d.d.ts.map +1 -0
- package/build/lib/mask/mask.test-d.js +102 -0
- package/build/lib/mask/mask.test-d.js.map +1 -0
- package/build/lib/mutation-type.d.ts +18 -0
- package/build/lib/mutation-type.d.ts.map +1 -0
- package/build/lib/mutation-type.js +16 -0
- package/build/lib/mutation-type.js.map +1 -0
- package/build/lib/task/$$.d.ts +3 -0
- package/build/lib/task/$$.d.ts.map +1 -0
- package/build/lib/task/$$.js +3 -0
- package/build/lib/task/$$.js.map +1 -0
- package/build/lib/task/$.d.ts +2 -0
- package/build/lib/task/$.d.ts.map +1 -0
- package/build/lib/task/$.js +2 -0
- package/build/lib/task/$.js.map +1 -0
- package/build/lib/task/report.d.ts +28 -0
- package/build/lib/task/report.d.ts.map +1 -0
- package/build/lib/task/report.js +33 -0
- package/build/lib/task/report.js.map +1 -0
- package/build/lib/task/task.d.ts +44 -0
- package/build/lib/task/task.d.ts.map +1 -0
- package/build/lib/task/task.js +63 -0
- package/build/lib/task/task.js.map +1 -0
- package/build/lib/version-history/index.d.ts +3 -0
- package/build/lib/version-history/index.d.ts.map +1 -0
- package/build/lib/version-history/index.js +2 -0
- package/build/lib/version-history/index.js.map +1 -0
- package/build/lib/version-history/types.d.ts +64 -0
- package/build/lib/version-history/types.d.ts.map +1 -0
- package/build/lib/version-history/types.js +5 -0
- package/build/lib/version-history/types.js.map +1 -0
- package/build/lib/version-history/version-history.d.ts +85 -0
- package/build/lib/version-history/version-history.d.ts.map +1 -0
- package/build/lib/version-history/version-history.js +248 -0
- package/build/lib/version-history/version-history.js.map +1 -0
- package/build/project-data.d.ts +0 -1
- package/build/project-data.d.ts.map +1 -1
- package/build/sandbox.d.ts +2 -0
- package/build/sandbox.d.ts.map +1 -0
- package/build/sandbox.js +18 -0
- package/build/sandbox.js.map +1 -0
- package/build/singletons/debug.d.ts +1 -1
- package/build/singletons/debug.d.ts.map +1 -1
- package/build/singletons/debug.js +1 -1
- package/build/singletons/debug.js.map +1 -1
- package/build/template/components/CodeBlockEnhancer.d.ts +2 -0
- package/build/template/components/CodeBlockEnhancer.d.ts.map +1 -0
- package/build/template/components/CodeBlockEnhancer.jsx +175 -0
- package/build/template/components/CodeBlockEnhancer.jsx.map +1 -0
- package/build/template/components/HamburgerMenu.d.ts +9 -0
- package/build/template/components/HamburgerMenu.d.ts.map +1 -0
- package/build/template/components/HamburgerMenu.jsx +53 -0
- package/build/template/components/HamburgerMenu.jsx.map +1 -0
- package/build/template/components/Link.jsx +1 -1
- package/build/template/components/Logo.d.ts +9 -0
- package/build/template/components/Logo.d.ts.map +1 -0
- package/build/template/components/Logo.jsx +29 -0
- package/build/template/components/Logo.jsx.map +1 -0
- package/build/template/components/NotFound.d.ts +2 -0
- package/build/template/components/NotFound.d.ts.map +1 -0
- package/build/template/components/NotFound.jsx +26 -0
- package/build/template/components/NotFound.jsx.map +1 -0
- package/build/template/components/ThemeToggle.d.ts +3 -0
- package/build/template/components/ThemeToggle.d.ts.map +1 -0
- package/build/template/components/ThemeToggle.jsx +10 -0
- package/build/template/components/ThemeToggle.jsx.map +1 -0
- package/build/template/components/content/$$.d.ts +2 -0
- package/build/template/components/content/$$.d.ts.map +1 -0
- package/build/template/components/content/$$.js +2 -0
- package/build/template/components/content/$$.js.map +1 -0
- package/build/template/components/sidebar/Sidebar.d.ts +2 -2
- package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
- package/build/template/components/sidebar/SidebarItem.d.ts +3 -3
- package/build/template/components/sidebar/SidebarItem.d.ts.map +1 -1
- package/build/template/components/sidebar/SidebarItem.jsx +3 -3
- package/build/template/components/sidebar/SidebarItem.jsx.map +1 -1
- package/build/template/contexts/ThemeContext.d.ts +12 -0
- package/build/template/contexts/ThemeContext.d.ts.map +1 -0
- package/build/template/contexts/ThemeContext.jsx +41 -0
- package/build/template/contexts/ThemeContext.jsx.map +1 -0
- package/build/template/routes/reference.d.ts.map +1 -1
- package/build/template/routes/reference.jsx +4 -8
- package/build/template/routes/reference.jsx.map +1 -1
- package/build/template/routes/root.d.ts.map +1 -1
- package/build/template/routes/root.jsx +192 -55
- package/build/template/routes/root.jsx.map +1 -1
- package/build/template/server/app.d.ts.map +1 -1
- package/build/template/server/app.js +2 -21
- package/build/template/server/app.js.map +1 -1
- package/package.json +27 -13
- package/src/api/api.ts +1 -0
- package/src/api/config/configurator.ts +28 -6
- package/src/api/config/load.ts +5 -5
- package/src/api/config-resolver/resolve.ts +2 -2
- package/src/api/content/$$.ts +6 -0
- package/src/api/content/$.test.ts +72 -0
- package/src/api/content/$.ts +1 -0
- package/src/api/content/metadata.ts +11 -0
- package/src/api/content/navbar.test.ts +55 -0
- package/src/api/content/navbar.ts +61 -0
- package/src/api/content/page.ts +12 -0
- package/src/api/content/scan.ts +117 -0
- package/src/api/content/sidebar.test.ts +297 -0
- package/src/api/content/sidebar.ts +283 -0
- package/src/api/content/utils.ts +7 -0
- package/src/api/schema/data-sources/schema-directory/schema-directory.ts +1 -1
- package/src/api/singletons/markdown/markdown.test.ts +1 -1
- package/src/api/static/index.ts +1 -0
- package/src/api/static/manifest.test.ts +106 -0
- package/src/api/static/manifest.ts +16 -0
- package/src/api/static/rebase.test.ts +229 -0
- package/src/api/static/rebase.ts +140 -0
- package/src/api/static/static.ts +2 -0
- package/src/api/utils/asset-url/asset-url.test.ts +4 -4
- package/src/api/vite/plugins/branding/index.ts +108 -0
- package/src/api/vite/plugins/build.ts +25 -1
- package/src/api/vite/plugins/core.ts +6 -7
- package/src/api/vite/plugins/main.ts +2 -0
- package/src/api/vite/plugins/pages.ts +131 -207
- package/src/api/vite/plugins/serve.ts +5 -5
- package/src/cli/_/self-contained-mode.ts +5 -5
- package/src/cli/commands/static/$default.ts +43 -0
- package/src/cli/commands/static/rebase.ts +37 -0
- package/src/cli/commands/static.ts +6 -0
- package/src/exports/components.ts +1 -0
- package/src/lib/demos/builder.ts +298 -0
- package/src/lib/demos/config-schema.ts +56 -0
- package/src/lib/demos/config.test.ts +193 -0
- package/src/lib/demos/config.ts +205 -0
- package/src/lib/demos/index.ts +9 -0
- package/src/lib/demos/ui/components.ts +739 -0
- package/src/lib/demos/ui/data-collector.ts +246 -0
- package/src/lib/demos/ui/landing-page-cli.ts +23 -0
- package/src/lib/demos/ui/landing-page.ts +126 -0
- package/src/lib/demos/ui/page-renderer.ts +124 -0
- package/src/lib/demos/utils.ts +43 -0
- package/src/lib/deployment/$$.ts +2 -0
- package/src/lib/deployment/$.test.ts +53 -0
- package/src/lib/deployment/$.ts +1 -0
- package/src/lib/deployment/metadata.ts +40 -0
- package/src/lib/deployment/path-manager.ts +186 -0
- package/src/lib/file-router/file-router.ts +0 -2
- package/src/lib/file-router/linter.test.ts +2 -0
- package/src/lib/file-router/route.ts +2 -0
- package/src/lib/file-router/scan.ts +26 -14
- package/src/lib/github-actions/git-controller.ts +151 -0
- package/src/lib/github-actions/github-actions.ts +6 -0
- package/src/lib/github-actions/index.ts +1 -0
- package/src/lib/github-actions/lib/get-pr-deployments.ts +76 -0
- package/src/lib/github-actions/pr-controller.test.ts +172 -0
- package/src/lib/github-actions/pr-controller.ts +183 -0
- package/src/lib/github-actions/run-step-cli.ts +84 -0
- package/src/lib/github-actions/runner.test.ts +192 -0
- package/src/lib/github-actions/runner.ts +226 -0
- package/src/lib/github-actions/schemas/context.ts +424 -0
- package/src/lib/github-actions/schemas/index.ts +5 -0
- package/src/lib/github-actions/search-module.test.ts +110 -0
- package/src/lib/github-actions/search-module.ts +76 -0
- package/src/lib/github-actions/step.test.ts +149 -0
- package/src/lib/github-actions/step.ts +232 -0
- package/src/lib/helpers.ts +4 -3
- package/src/lib/kit-temp.test-d.ts +115 -0
- package/src/lib/kit-temp.test.ts +127 -0
- package/src/lib/kit-temp.ts +128 -14
- package/src/lib/mask/$$.ts +2 -0
- package/src/lib/mask/$.test.ts +248 -0
- package/src/lib/mask/$.ts +1 -0
- package/src/lib/mask/apply.ts +134 -0
- package/src/lib/mask/mask.test-d.ts +144 -0
- package/src/lib/mask/mask.ts +244 -0
- package/src/lib/mutation-type.ts +20 -0
- package/src/lib/shiki/shiki.test.ts +1 -1
- package/src/lib/task/$$.ts +2 -0
- package/src/lib/task/$.test.ts +209 -0
- package/src/lib/task/$.ts +1 -0
- package/src/lib/task/report.ts +72 -0
- package/src/lib/task/task.ts +112 -0
- package/src/lib/version-history/index.test.ts +196 -0
- package/src/lib/version-history/index.ts +4 -0
- package/src/lib/version-history/types.ts +68 -0
- package/src/lib/version-history/version-history.ts +293 -0
- package/src/project-data.ts +0 -1
- package/src/sandbox.ts +20 -0
- package/src/singletons/debug.ts +1 -1
- package/src/template/components/CodeBlockEnhancer.tsx +192 -0
- package/src/template/components/HamburgerMenu.tsx +96 -0
- package/src/template/components/Link.tsx +1 -1
- package/src/template/components/Logo.tsx +46 -0
- package/src/template/components/NotFound.tsx +28 -0
- package/src/template/components/ThemeToggle.tsx +21 -0
- package/src/template/components/content/$$.ts +1 -0
- package/src/template/components/sidebar/Sidebar.tsx +2 -2
- package/src/template/components/sidebar/SidebarItem.tsx +12 -12
- package/src/template/contexts/ThemeContext.tsx +60 -0
- package/src/template/routes/reference.tsx +4 -8
- package/src/template/routes/root.tsx +216 -76
- package/src/template/server/app.ts +2 -27
- package/build/lib/file-router/scan-tree.d.ts +0 -20
- package/build/lib/file-router/scan-tree.d.ts.map +0 -1
- package/build/lib/file-router/scan-tree.js +0 -158
- package/build/lib/file-router/scan-tree.js.map +0 -1
- package/build/lib/file-router/sidebar/index.d.ts +0 -3
- package/build/lib/file-router/sidebar/index.d.ts.map +0 -1
- package/build/lib/file-router/sidebar/index.js +0 -4
- package/build/lib/file-router/sidebar/index.js.map +0 -1
- package/build/lib/file-router/sidebar/sidebar-tree.d.ts +0 -9
- package/build/lib/file-router/sidebar/sidebar-tree.d.ts.map +0 -1
- package/build/lib/file-router/sidebar/sidebar-tree.js +0 -85
- package/build/lib/file-router/sidebar/sidebar-tree.js.map +0 -1
- package/build/lib/file-router/sidebar/types.d.ts +0 -17
- package/build/lib/file-router/sidebar/types.d.ts.map +0 -1
- package/build/lib/file-router/sidebar/types.js +0 -2
- package/build/lib/file-router/sidebar/types.js.map +0 -1
- package/build/lib/tree/index.d.ts +0 -3
- package/build/lib/tree/index.d.ts.map +0 -1
- package/build/lib/tree/index.js +0 -2
- package/build/lib/tree/index.js.map +0 -1
- package/build/lib/tree/tree.d.ts +0 -62
- package/build/lib/tree/tree.d.ts.map +0 -1
- package/build/lib/tree/tree.js +0 -134
- package/build/lib/tree/tree.js.map +0 -1
- package/src/lib/file-router/scan-tree.test.ts +0 -189
- package/src/lib/file-router/scan-tree.ts +0 -205
- package/src/lib/file-router/sidebar/index.ts +0 -3
- package/src/lib/file-router/sidebar/sidebar-tree.test.ts +0 -123
- package/src/lib/file-router/sidebar/sidebar-tree.ts +0 -110
- package/src/lib/file-router/sidebar/types.ts +0 -19
- package/src/lib/tree/index.ts +0 -2
- package/src/lib/tree/tree.test.ts +0 -117
- package/src/lib/tree/tree.ts +0 -183
@@ -0,0 +1,186 @@
|
|
1
|
+
/**
|
2
|
+
* Deployment path management for demos
|
3
|
+
*/
|
4
|
+
|
5
|
+
import { promises as fs } from 'node:fs'
|
6
|
+
import { join } from 'node:path'
|
7
|
+
|
8
|
+
export interface RedirectConfig {
|
9
|
+
from: string
|
10
|
+
to: string
|
11
|
+
type?: 'html' | 'meta'
|
12
|
+
}
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Manages deployment paths and base path updates for demo files
|
16
|
+
*/
|
17
|
+
export class PathManager {
|
18
|
+
constructor() {}
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Generate HTML redirect pages
|
22
|
+
*/
|
23
|
+
async generateRedirects(redirects: RedirectConfig[], outputDir: string): Promise<void> {
|
24
|
+
try {
|
25
|
+
for (const redirect of redirects) {
|
26
|
+
const redirectPath = join(outputDir, redirect.from, 'index.html')
|
27
|
+
const redirectDir = join(outputDir, redirect.from)
|
28
|
+
|
29
|
+
await fs.mkdir(redirectDir, { recursive: true })
|
30
|
+
|
31
|
+
const html = this.createRedirectHtml(redirect.to)
|
32
|
+
await fs.writeFile(redirectPath, html)
|
33
|
+
}
|
34
|
+
} catch (error) {
|
35
|
+
throw new Error(`Failed to generate redirects: ${error instanceof Error ? error.message : String(error)}`)
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Create convenience redirects for demo examples
|
41
|
+
*/
|
42
|
+
async createDemoRedirects(
|
43
|
+
examples: string[],
|
44
|
+
outputDir: string,
|
45
|
+
targetBasePath: string = '/latest/',
|
46
|
+
): Promise<void> {
|
47
|
+
const redirects: RedirectConfig[] = examples.map(example => ({
|
48
|
+
from: example,
|
49
|
+
to: `${targetBasePath}${example}/`,
|
50
|
+
}))
|
51
|
+
|
52
|
+
await this.generateRedirects(redirects, outputDir)
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Validate deployment structure
|
57
|
+
*/
|
58
|
+
async validateDeploymentStructure(deploymentDir: string): Promise<{
|
59
|
+
valid: boolean
|
60
|
+
errors: string[]
|
61
|
+
warnings: string[]
|
62
|
+
}> {
|
63
|
+
const errors: string[] = []
|
64
|
+
const warnings: string[] = []
|
65
|
+
|
66
|
+
try {
|
67
|
+
// Check if deployment directory exists
|
68
|
+
await fs.access(deploymentDir)
|
69
|
+
} catch {
|
70
|
+
errors.push(`Deployment directory does not exist: ${deploymentDir}`)
|
71
|
+
return { valid: false, errors, warnings }
|
72
|
+
}
|
73
|
+
|
74
|
+
try {
|
75
|
+
// Check for index.html
|
76
|
+
const indexPath = join(deploymentDir, 'index.html')
|
77
|
+
await fs.access(indexPath)
|
78
|
+
} catch {
|
79
|
+
warnings.push('No index.html found in deployment root')
|
80
|
+
}
|
81
|
+
|
82
|
+
return {
|
83
|
+
valid: errors.length === 0,
|
84
|
+
errors,
|
85
|
+
warnings,
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Clean up old deployment directories
|
91
|
+
*/
|
92
|
+
async cleanupOldDeployments(
|
93
|
+
parentDir: string,
|
94
|
+
keepVersions: string[],
|
95
|
+
dryRun: boolean = false,
|
96
|
+
): Promise<{ removed: string[]; kept: string[]; errors: string[] }> {
|
97
|
+
const removed: string[] = []
|
98
|
+
const kept: string[] = []
|
99
|
+
const errors: string[] = []
|
100
|
+
|
101
|
+
try {
|
102
|
+
const entries = await fs.readdir(parentDir, { withFileTypes: true })
|
103
|
+
const directories = entries
|
104
|
+
.filter(entry => entry.isDirectory())
|
105
|
+
.map(entry => entry.name)
|
106
|
+
|
107
|
+
for (const dir of directories) {
|
108
|
+
if (keepVersions.includes(dir)) {
|
109
|
+
kept.push(dir)
|
110
|
+
} else if (this.isSemverDirectory(dir)) {
|
111
|
+
if (!dryRun) {
|
112
|
+
try {
|
113
|
+
await fs.rm(join(parentDir, dir), { recursive: true, force: true })
|
114
|
+
removed.push(dir)
|
115
|
+
} catch (error) {
|
116
|
+
errors.push(`Failed to remove ${dir}: ${error}`)
|
117
|
+
}
|
118
|
+
} else {
|
119
|
+
removed.push(dir) // Dry run - just track what would be removed
|
120
|
+
}
|
121
|
+
} else {
|
122
|
+
kept.push(dir) // Keep non-semver directories
|
123
|
+
}
|
124
|
+
}
|
125
|
+
} catch (error) {
|
126
|
+
throw new Error(
|
127
|
+
`Failed to cleanup deployments in ${parentDir}: ${error instanceof Error ? error.message : String(error)}`,
|
128
|
+
)
|
129
|
+
}
|
130
|
+
|
131
|
+
return { removed, kept, errors }
|
132
|
+
}
|
133
|
+
|
134
|
+
// Private helper methods
|
135
|
+
|
136
|
+
private createRedirectHtml(targetUrl: string): string {
|
137
|
+
return `<!DOCTYPE html>
|
138
|
+
<html lang="en">
|
139
|
+
<head>
|
140
|
+
<meta charset="UTF-8">
|
141
|
+
<meta http-equiv="refresh" content="0; url=${targetUrl}">
|
142
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
143
|
+
<title>Redirecting...</title>
|
144
|
+
<style>
|
145
|
+
body {
|
146
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
147
|
+
display: flex;
|
148
|
+
align-items: center;
|
149
|
+
justify-content: center;
|
150
|
+
height: 100vh;
|
151
|
+
margin: 0;
|
152
|
+
background: #f5f5f5;
|
153
|
+
}
|
154
|
+
.redirect-message {
|
155
|
+
text-align: center;
|
156
|
+
padding: 2rem;
|
157
|
+
background: white;
|
158
|
+
border-radius: 8px;
|
159
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
160
|
+
}
|
161
|
+
.redirect-message a {
|
162
|
+
color: #0066cc;
|
163
|
+
text-decoration: none;
|
164
|
+
}
|
165
|
+
.redirect-message a:hover {
|
166
|
+
text-decoration: underline;
|
167
|
+
}
|
168
|
+
</style>
|
169
|
+
</head>
|
170
|
+
<body>
|
171
|
+
<div class="redirect-message">
|
172
|
+
<h1>Redirecting...</h1>
|
173
|
+
<p>If you are not redirected automatically, <a href="${targetUrl}">click here</a>.</p>
|
174
|
+
</div>
|
175
|
+
<script>
|
176
|
+
window.location.href = '${targetUrl}';
|
177
|
+
</script>
|
178
|
+
</body>
|
179
|
+
</html>`
|
180
|
+
}
|
181
|
+
|
182
|
+
private isSemverDirectory(name: string): boolean {
|
183
|
+
// Check if directory name looks like a semver version
|
184
|
+
return /^\d+\.\d+\.\d+/.test(name)
|
185
|
+
}
|
186
|
+
}
|
@@ -36,6 +36,8 @@ export const pathToExpression = (path: Path) => {
|
|
36
36
|
export interface Route {
|
37
37
|
logical: RouteLogical
|
38
38
|
file: RouteFile
|
39
|
+
id: string // Absolute file path for unique identification
|
40
|
+
parentId: string | null // Parent directory path, null for root-level files
|
39
41
|
}
|
40
42
|
|
41
43
|
export interface RouteLogical {
|
@@ -1,9 +1,7 @@
|
|
1
1
|
import { TinyGlobby } from '#dep/tiny-globby/index'
|
2
|
-
import { Tree } from '#lib/tree/index'
|
3
2
|
import { Path, Str } from '@wollybeard/kit'
|
4
3
|
import { type Diagnostic, lint } from './linter.ts'
|
5
|
-
import { type Route, type RouteFile, type RouteLogical
|
6
|
-
import { scanTree } from './scan-tree.ts'
|
4
|
+
import { type Route, type RouteFile, type RouteLogical } from './route.ts'
|
7
5
|
|
8
6
|
//
|
9
7
|
//
|
@@ -47,21 +45,21 @@ export const scan = async (parameters: {
|
|
47
45
|
dir: string
|
48
46
|
glob?: string
|
49
47
|
}): Promise<ScanResult> => {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
routes.push(node.value.route)
|
58
|
-
}
|
48
|
+
const { dir, glob = `**/*.{md,mdx}` } = parameters
|
49
|
+
|
50
|
+
// Get all files directly
|
51
|
+
const filePaths = await TinyGlobby.glob(glob, {
|
52
|
+
absolute: true,
|
53
|
+
cwd: dir,
|
54
|
+
onlyFiles: true,
|
59
55
|
})
|
60
56
|
|
57
|
+
// Convert to routes
|
58
|
+
const routes = filePaths.map(filePath => filePathToRoute(filePath, dir))
|
59
|
+
|
61
60
|
// Apply linting
|
62
61
|
const lintResult = lint(routes)
|
63
62
|
|
64
|
-
// Routes are already sorted by the tree structure
|
65
63
|
return lintResult
|
66
64
|
}
|
67
65
|
|
@@ -74,14 +72,28 @@ export const filePathToRoute = (filePathExpression: string, rootDir: string): Ro
|
|
74
72
|
}
|
75
73
|
const logical = filePathToRouteLogical(file.path.relative)
|
76
74
|
|
75
|
+
// Generate id and parentId for tree building
|
76
|
+
const id = filePathExpression // Use absolute path as unique ID
|
77
|
+
const relativePath = Path.relative(rootDir, filePathExpression)
|
78
|
+
const parentDir = Path.dirname(relativePath)
|
79
|
+
const parentId = parentDir === '.' ? null : Path.join(rootDir, parentDir)
|
80
|
+
|
77
81
|
return {
|
78
82
|
logical,
|
79
83
|
file,
|
84
|
+
id,
|
85
|
+
parentId,
|
80
86
|
}
|
81
87
|
}
|
82
88
|
|
83
89
|
export const filePathToRouteLogical = (filePath: Path.Parsed): RouteLogical => {
|
84
|
-
const
|
90
|
+
const dirSegments = Str.split(Str.removeSurrounding(filePath.dir, Path.sep), Path.sep)
|
91
|
+
|
92
|
+
// Parse numbered prefixes from directory segments
|
93
|
+
const dirPath = dirSegments.map(segment => {
|
94
|
+
const prefixMatch = Str.match(segment, conventions.numberedPrefix.pattern)
|
95
|
+
return prefixMatch?.groups.name ?? segment
|
96
|
+
})
|
85
97
|
|
86
98
|
// Parse numbered prefix from filename
|
87
99
|
const prefixMatch = Str.match(filePath.name, conventions.numberedPrefix.pattern)
|
@@ -0,0 +1,151 @@
|
|
1
|
+
/**
|
2
|
+
* Git controller for GitHub Actions
|
3
|
+
* Provides simple git operations without exposing subprocess details
|
4
|
+
*/
|
5
|
+
|
6
|
+
import type { $ as ZxDollar } from 'zx'
|
7
|
+
|
8
|
+
export interface GitCommitOptions {
|
9
|
+
/**
|
10
|
+
* Commit message
|
11
|
+
*/
|
12
|
+
message: string
|
13
|
+
/**
|
14
|
+
* Optional commit body for additional details
|
15
|
+
*/
|
16
|
+
body?: string
|
17
|
+
/**
|
18
|
+
* Files or patterns to stage (defaults to '.')
|
19
|
+
*/
|
20
|
+
add?: string | string[]
|
21
|
+
/**
|
22
|
+
* Working directory (defaults to current directory)
|
23
|
+
*/
|
24
|
+
cwd?: string
|
25
|
+
/**
|
26
|
+
* Whether to push after committing (defaults to true)
|
27
|
+
*/
|
28
|
+
push?: boolean
|
29
|
+
/**
|
30
|
+
* Whether to automatically configure the user to be GitHub (defaults to true)
|
31
|
+
*/
|
32
|
+
autoConfigureUser?: boolean
|
33
|
+
}
|
34
|
+
|
35
|
+
export interface GitController {
|
36
|
+
/**
|
37
|
+
* Create a commit with the staged changes
|
38
|
+
*/
|
39
|
+
commit(options: GitCommitOptions): Promise<boolean>
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Check if there are any changes (staged or unstaged)
|
43
|
+
*/
|
44
|
+
hasChanges(cwd?: string): Promise<boolean>
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Configure git user for commits
|
48
|
+
*/
|
49
|
+
configureUser(name?: string, email?: string): Promise<void>
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Create a git controller instance
|
54
|
+
*/
|
55
|
+
export function createGitController($: typeof ZxDollar): GitController {
|
56
|
+
const api: GitController = {
|
57
|
+
async commit(options) {
|
58
|
+
const {
|
59
|
+
message,
|
60
|
+
body,
|
61
|
+
add = '.',
|
62
|
+
cwd,
|
63
|
+
push = true,
|
64
|
+
autoConfigureUser = true,
|
65
|
+
} = options
|
66
|
+
|
67
|
+
const hasChanges = await api.hasChanges('gh-pages')
|
68
|
+
if (!hasChanges) {
|
69
|
+
console.log('No changes to commit')
|
70
|
+
return false
|
71
|
+
}
|
72
|
+
|
73
|
+
if (autoConfigureUser) {
|
74
|
+
await api.configureUser()
|
75
|
+
}
|
76
|
+
|
77
|
+
try {
|
78
|
+
// Stage files
|
79
|
+
const filesToAdd = Array.isArray(add) ? add : [add]
|
80
|
+
for (const pattern of filesToAdd) {
|
81
|
+
if (cwd) {
|
82
|
+
await $`cd ${cwd} && git add ${pattern}`
|
83
|
+
} else {
|
84
|
+
await $`git add ${pattern}`
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
// Check if there are changes to commit
|
89
|
+
const statusCmd = cwd ? $`cd ${cwd} && git status --porcelain` : $`git status --porcelain`
|
90
|
+
const status = await statusCmd
|
91
|
+
|
92
|
+
if (!status.stdout.trim()) {
|
93
|
+
return false // No changes to commit
|
94
|
+
}
|
95
|
+
|
96
|
+
// Build commit message
|
97
|
+
let fullMessage = message
|
98
|
+
if (body) {
|
99
|
+
fullMessage = `${message}\n\n${body}`
|
100
|
+
}
|
101
|
+
|
102
|
+
// Commit
|
103
|
+
if (cwd) {
|
104
|
+
await $`cd ${cwd} && git commit -m ${fullMessage}`
|
105
|
+
} else {
|
106
|
+
await $`git commit -m ${fullMessage}`
|
107
|
+
}
|
108
|
+
|
109
|
+
// Push if requested
|
110
|
+
if (push) {
|
111
|
+
if (cwd) {
|
112
|
+
await $`cd ${cwd} && git push`
|
113
|
+
} else {
|
114
|
+
await $`git push`
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
return true
|
119
|
+
} catch (error) {
|
120
|
+
throw new Error(`Git commit failed: ${error}`)
|
121
|
+
}
|
122
|
+
},
|
123
|
+
|
124
|
+
async hasChanges(cwd) {
|
125
|
+
try {
|
126
|
+
const cmd = cwd
|
127
|
+
? $`cd ${cwd} && git status --porcelain`
|
128
|
+
: $`git status --porcelain`
|
129
|
+
|
130
|
+
const result = await cmd
|
131
|
+
return result.stdout.trim().length > 0
|
132
|
+
} catch (error) {
|
133
|
+
throw new Error(`Failed to check git status: ${error}`)
|
134
|
+
}
|
135
|
+
},
|
136
|
+
|
137
|
+
async configureUser(name, email) {
|
138
|
+
try {
|
139
|
+
const userName = name || 'github-actions[bot]'
|
140
|
+
const userEmail = email || 'github-actions[bot]@users.noreply.github.com'
|
141
|
+
|
142
|
+
await $`git config user.name ${userName}`
|
143
|
+
await $`git config user.email ${userEmail}`
|
144
|
+
} catch (error) {
|
145
|
+
throw new Error(`Failed to configure git user: ${error}`)
|
146
|
+
}
|
147
|
+
},
|
148
|
+
}
|
149
|
+
|
150
|
+
return api
|
151
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * as GitHubActions from './github-actions.ts'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import type { GitHub } from '@actions/github/lib/utils.ts'
|
2
|
+
|
3
|
+
export interface Deployment {
|
4
|
+
sha: string
|
5
|
+
shortSha: string
|
6
|
+
createdAt: string
|
7
|
+
status?: string
|
8
|
+
}
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Fetch deployments for a specific PR using GitHub API
|
12
|
+
*/
|
13
|
+
export async function fetchPullRequestDeployments(
|
14
|
+
github: InstanceType<typeof GitHub>,
|
15
|
+
owner: string,
|
16
|
+
repo: string,
|
17
|
+
prNumber: string | number,
|
18
|
+
): Promise<Deployment[]> {
|
19
|
+
const deployments: Deployment[] = []
|
20
|
+
|
21
|
+
try {
|
22
|
+
// Get all deployments for this PR's environment
|
23
|
+
const { data: ghDeployments } = await github.rest.repos.listDeployments({
|
24
|
+
owner,
|
25
|
+
repo,
|
26
|
+
environment: `pr-${prNumber}`,
|
27
|
+
per_page: 100,
|
28
|
+
})
|
29
|
+
|
30
|
+
// Debug logging
|
31
|
+
console.log(`Found ${ghDeployments.length} deployments for PR #${prNumber}`)
|
32
|
+
|
33
|
+
// Process each deployment
|
34
|
+
for (const deployment of ghDeployments) {
|
35
|
+
console.log(
|
36
|
+
`Processing deployment: ${deployment.id}, SHA: ${deployment.sha.substring(0, 7)}, Ref: ${deployment.ref}`,
|
37
|
+
)
|
38
|
+
|
39
|
+
// Get the latest status for this deployment
|
40
|
+
const { data: statuses } = await github.rest.repos.listDeploymentStatuses({
|
41
|
+
owner,
|
42
|
+
repo,
|
43
|
+
deployment_id: deployment.id,
|
44
|
+
per_page: 1,
|
45
|
+
})
|
46
|
+
|
47
|
+
const latestStatus = statuses[0]
|
48
|
+
const state = latestStatus?.state
|
49
|
+
|
50
|
+
console.log(` Status: ${state || 'no status'}`)
|
51
|
+
|
52
|
+
// Include successful and inactive deployments
|
53
|
+
if (state === 'success' || state === 'inactive') {
|
54
|
+
const shortSha = deployment.sha.substring(0, 7)
|
55
|
+
|
56
|
+
deployments.push({
|
57
|
+
sha: deployment.sha,
|
58
|
+
shortSha,
|
59
|
+
createdAt: deployment.created_at,
|
60
|
+
status: state,
|
61
|
+
})
|
62
|
+
console.log(` Added to deployments list`)
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
// Sort by creation date (newest first)
|
67
|
+
deployments.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
|
68
|
+
|
69
|
+
console.log(`Returning ${deployments.length} successful deployments for PR #${prNumber}`)
|
70
|
+
} catch (error) {
|
71
|
+
console.error(`Error fetching deployments for PR #${prNumber}:`, error)
|
72
|
+
throw error
|
73
|
+
}
|
74
|
+
|
75
|
+
return deployments
|
76
|
+
}
|
@@ -0,0 +1,172 @@
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
2
|
+
import { createPullRequestController } from './pr-controller.ts'
|
3
|
+
|
4
|
+
describe('createPRController', () => {
|
5
|
+
const mockGitHub = {
|
6
|
+
rest: {
|
7
|
+
issues: {
|
8
|
+
listComments: vi.fn(),
|
9
|
+
createComment: vi.fn(),
|
10
|
+
updateComment: vi.fn(),
|
11
|
+
deleteComment: vi.fn(),
|
12
|
+
},
|
13
|
+
},
|
14
|
+
} as any
|
15
|
+
|
16
|
+
const mockContext = {
|
17
|
+
eventName: 'pull_request',
|
18
|
+
repo: {
|
19
|
+
owner: 'test-owner',
|
20
|
+
repo: 'test-repo',
|
21
|
+
},
|
22
|
+
payload: {
|
23
|
+
pull_request: {
|
24
|
+
number: 123,
|
25
|
+
},
|
26
|
+
},
|
27
|
+
} as any
|
28
|
+
|
29
|
+
beforeEach(() => {
|
30
|
+
vi.clearAllMocks()
|
31
|
+
})
|
32
|
+
|
33
|
+
it('returns no-op controller for non-PR events', () => {
|
34
|
+
const nonPRContext = {
|
35
|
+
...mockContext,
|
36
|
+
eventName: 'push',
|
37
|
+
payload: {},
|
38
|
+
}
|
39
|
+
|
40
|
+
const controller = createPullRequestController(mockGitHub, nonPRContext)
|
41
|
+
expect(controller).toBeDefined()
|
42
|
+
expect(controller.isActive).toBe(false)
|
43
|
+
expect(controller.number).toBe(0)
|
44
|
+
})
|
45
|
+
|
46
|
+
it('returns active PR controller for PR events', () => {
|
47
|
+
const controller = createPullRequestController(mockGitHub, mockContext)
|
48
|
+
expect(controller).toBeDefined()
|
49
|
+
expect(controller.isActive).toBe(true)
|
50
|
+
expect(controller.number).toBe(123)
|
51
|
+
})
|
52
|
+
|
53
|
+
describe('PR controller methods', () => {
|
54
|
+
it('creates new comment when none exists', async () => {
|
55
|
+
mockGitHub.rest.issues.listComments.mockResolvedValue({ data: [] })
|
56
|
+
|
57
|
+
const controller = createPullRequestController(mockGitHub, mockContext)!
|
58
|
+
await controller.comment({ id: 'test', content: 'Hello world' })
|
59
|
+
|
60
|
+
expect(mockGitHub.rest.issues.createComment).toHaveBeenCalledWith({
|
61
|
+
owner: 'test-owner',
|
62
|
+
repo: 'test-repo',
|
63
|
+
issue_number: 123,
|
64
|
+
body: 'Hello world\n\n<!-- comment-id: test -->',
|
65
|
+
})
|
66
|
+
})
|
67
|
+
|
68
|
+
it('uses default comment ID when not provided', async () => {
|
69
|
+
mockGitHub.rest.issues.listComments.mockResolvedValue({ data: [] })
|
70
|
+
|
71
|
+
const controller = createPullRequestController(mockGitHub, mockContext, 'pr-comment')!
|
72
|
+
await controller.comment({ content: 'Hello world' })
|
73
|
+
|
74
|
+
expect(mockGitHub.rest.issues.createComment).toHaveBeenCalledWith({
|
75
|
+
owner: 'test-owner',
|
76
|
+
repo: 'test-repo',
|
77
|
+
issue_number: 123,
|
78
|
+
body: 'Hello world\n\n<!-- comment-id: pr-comment -->',
|
79
|
+
})
|
80
|
+
})
|
81
|
+
|
82
|
+
it('updates existing comment', async () => {
|
83
|
+
mockGitHub.rest.issues.listComments.mockResolvedValue({
|
84
|
+
data: [
|
85
|
+
{
|
86
|
+
id: 456,
|
87
|
+
body: 'Old content\n\n<!-- comment-id: test -->',
|
88
|
+
},
|
89
|
+
],
|
90
|
+
})
|
91
|
+
|
92
|
+
const controller = createPullRequestController(mockGitHub, mockContext)!
|
93
|
+
await controller.comment({ id: 'test', content: 'New content' })
|
94
|
+
|
95
|
+
expect(mockGitHub.rest.issues.updateComment).toHaveBeenCalledWith({
|
96
|
+
owner: 'test-owner',
|
97
|
+
repo: 'test-repo',
|
98
|
+
comment_id: 456,
|
99
|
+
body: 'New content\n\n<!-- comment-id: test -->',
|
100
|
+
})
|
101
|
+
})
|
102
|
+
|
103
|
+
it('deletes comment by ID', async () => {
|
104
|
+
mockGitHub.rest.issues.listComments.mockResolvedValue({
|
105
|
+
data: [
|
106
|
+
{
|
107
|
+
id: 456,
|
108
|
+
body: 'Content\n\n<!-- comment-id: test -->',
|
109
|
+
},
|
110
|
+
],
|
111
|
+
})
|
112
|
+
|
113
|
+
const controller = createPullRequestController(mockGitHub, mockContext)!
|
114
|
+
await controller.deleteComment('test')
|
115
|
+
|
116
|
+
expect(mockGitHub.rest.issues.deleteComment).toHaveBeenCalledWith({
|
117
|
+
owner: 'test-owner',
|
118
|
+
repo: 'test-repo',
|
119
|
+
comment_id: 456,
|
120
|
+
})
|
121
|
+
})
|
122
|
+
|
123
|
+
it('handles issue_comment events on PRs', () => {
|
124
|
+
const issueCommentContext = {
|
125
|
+
...mockContext,
|
126
|
+
eventName: 'issue_comment',
|
127
|
+
payload: {
|
128
|
+
issue: {
|
129
|
+
number: 789,
|
130
|
+
pull_request: {}, // Presence indicates it's a PR
|
131
|
+
},
|
132
|
+
},
|
133
|
+
}
|
134
|
+
|
135
|
+
const controller = createPullRequestController(mockGitHub, issueCommentContext)
|
136
|
+
expect(controller).toBeDefined()
|
137
|
+
expect(controller.number).toBe(789)
|
138
|
+
})
|
139
|
+
})
|
140
|
+
|
141
|
+
describe('No-op PR controller', () => {
|
142
|
+
it('throws error for non-optional comments', async () => {
|
143
|
+
const nonPRContext = {
|
144
|
+
...mockContext,
|
145
|
+
eventName: 'push',
|
146
|
+
payload: {},
|
147
|
+
}
|
148
|
+
|
149
|
+
const controller = createPullRequestController(mockGitHub, nonPRContext)
|
150
|
+
|
151
|
+
await expect(controller.comment({ content: 'Test' })).rejects.toThrow(
|
152
|
+
'Not in a PR context, cannot create comment',
|
153
|
+
)
|
154
|
+
})
|
155
|
+
|
156
|
+
it('logs and continues for optional comments', async () => {
|
157
|
+
const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
|
158
|
+
const nonPRContext = {
|
159
|
+
...mockContext,
|
160
|
+
eventName: 'push',
|
161
|
+
payload: {},
|
162
|
+
}
|
163
|
+
|
164
|
+
const controller = createPullRequestController(mockGitHub, nonPRContext)
|
165
|
+
|
166
|
+
await expect(controller.comment({ content: 'Test', optional: true })).resolves.not.toThrow()
|
167
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('[skip] Not in a PR context, cannot create comment')
|
168
|
+
|
169
|
+
consoleLogSpy.mockRestore()
|
170
|
+
})
|
171
|
+
})
|
172
|
+
})
|