polen 0.9.1-next.2 → 0.10.0-next.10
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/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 +1 -1
- 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/root.d.ts.map +1 -1
- package/build/template/routes/root.jsx +66 -53
- 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/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 +8 -8
- package/src/template/contexts/ThemeContext.tsx +60 -0
- package/src/template/routes/root.tsx +85 -74
- 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,149 @@
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
2
|
+
import { z } from 'zod/v4'
|
3
|
+
import { createStep } from './step.ts'
|
4
|
+
|
5
|
+
describe('defineWorkflowStep', () => {
|
6
|
+
const mockCore = {
|
7
|
+
startGroup: vi.fn(),
|
8
|
+
endGroup: vi.fn(),
|
9
|
+
debug: vi.fn(),
|
10
|
+
info: vi.fn(),
|
11
|
+
warning: vi.fn(),
|
12
|
+
error: vi.fn(),
|
13
|
+
setOutput: vi.fn(),
|
14
|
+
} as any
|
15
|
+
|
16
|
+
const mockContext = {
|
17
|
+
core: mockCore,
|
18
|
+
github: {} as any,
|
19
|
+
context: {} as any,
|
20
|
+
$: {} as any,
|
21
|
+
fs: {} as any,
|
22
|
+
} as any
|
23
|
+
|
24
|
+
beforeEach(() => {
|
25
|
+
vi.clearAllMocks()
|
26
|
+
})
|
27
|
+
|
28
|
+
it('executes step with validated inputs', async () => {
|
29
|
+
const TestStep = createStep({
|
30
|
+
name: 'test-step',
|
31
|
+
description: 'Test step',
|
32
|
+
inputs: z.object({
|
33
|
+
required: z.string(),
|
34
|
+
optional: z.string().optional(),
|
35
|
+
}),
|
36
|
+
outputs: z.object({ result: z.string() }),
|
37
|
+
async run({ inputs }) {
|
38
|
+
return { result: `Got ${inputs.required}` }
|
39
|
+
},
|
40
|
+
})
|
41
|
+
|
42
|
+
// Create context with PR controller
|
43
|
+
const contextWithPR = {
|
44
|
+
...mockContext,
|
45
|
+
pr: {
|
46
|
+
number: 0,
|
47
|
+
isActive: false,
|
48
|
+
comment: vi.fn(),
|
49
|
+
deleteComment: vi.fn(),
|
50
|
+
getComments: vi.fn(),
|
51
|
+
},
|
52
|
+
}
|
53
|
+
|
54
|
+
const result = await TestStep.run({
|
55
|
+
...contextWithPR,
|
56
|
+
inputs: {
|
57
|
+
required: 'value',
|
58
|
+
optional: 'optional-value',
|
59
|
+
},
|
60
|
+
})
|
61
|
+
|
62
|
+
expect(result).toEqual({ result: 'Got value' })
|
63
|
+
})
|
64
|
+
|
65
|
+
it('validates output types', async () => {
|
66
|
+
const TestStep = createStep({
|
67
|
+
name: 'test-step',
|
68
|
+
description: 'Test step',
|
69
|
+
inputs: z.object({
|
70
|
+
required: z.string(),
|
71
|
+
}),
|
72
|
+
outputs: z.object({ result: z.string() }),
|
73
|
+
async run({ inputs }) {
|
74
|
+
return { result: inputs.required }
|
75
|
+
},
|
76
|
+
})
|
77
|
+
|
78
|
+
// Outputs are validated in the runner, not in execute
|
79
|
+
expect(TestStep.definition.outputsSchema).toBeDefined()
|
80
|
+
expect(TestStep.definition.inputsSchema).toBeDefined()
|
81
|
+
})
|
82
|
+
|
83
|
+
it('step definition contains all metadata', async () => {
|
84
|
+
const TestStep = createStep({
|
85
|
+
name: 'test-step',
|
86
|
+
description: 'Test step',
|
87
|
+
inputs: z.object({
|
88
|
+
number: z.number(),
|
89
|
+
}),
|
90
|
+
outputs: z.object({ result: z.string() }),
|
91
|
+
async run() {
|
92
|
+
return { result: 'ok' }
|
93
|
+
},
|
94
|
+
})
|
95
|
+
|
96
|
+
expect(TestStep.definition.name).toBe('test-step')
|
97
|
+
expect(TestStep.definition.description).toBe('Test step')
|
98
|
+
expect(TestStep.definition.inputsSchema).toBeDefined()
|
99
|
+
expect(TestStep.definition.outputsSchema).toBeDefined()
|
100
|
+
})
|
101
|
+
|
102
|
+
// todo: this test is now a static type error, update to refelct that
|
103
|
+
// it('does not warn for non-object schemas', async () => {
|
104
|
+
// const TestStep = defineStep({
|
105
|
+
// name: 'test-step',
|
106
|
+
// description: 'Test step',
|
107
|
+
// inputs: z.string(),
|
108
|
+
// outputs: z.object({ result: z.string() }),
|
109
|
+
// async run({ inputs }) {
|
110
|
+
// return { result: inputs }
|
111
|
+
// },
|
112
|
+
// })
|
113
|
+
|
114
|
+
// await TestStep(mockContext, 'just-a-string')
|
115
|
+
|
116
|
+
// expect(mockCore.warning).not.toHaveBeenCalled()
|
117
|
+
// })
|
118
|
+
|
119
|
+
it('always provides PR controller', async () => {
|
120
|
+
const mockPR = {
|
121
|
+
number: 123,
|
122
|
+
isActive: true,
|
123
|
+
comment: vi.fn(),
|
124
|
+
deleteComment: vi.fn(),
|
125
|
+
getComments: vi.fn(),
|
126
|
+
}
|
127
|
+
|
128
|
+
const contextWithPR = {
|
129
|
+
...mockContext,
|
130
|
+
pr: mockPR,
|
131
|
+
}
|
132
|
+
|
133
|
+
const TestStep = createStep({
|
134
|
+
name: 'test-step',
|
135
|
+
description: 'Test step with PR',
|
136
|
+
inputs: z.object({}),
|
137
|
+
outputs: z.object({ isActive: z.boolean() }),
|
138
|
+
async run({ pr }) {
|
139
|
+
return { isActive: pr.isActive }
|
140
|
+
},
|
141
|
+
})
|
142
|
+
|
143
|
+
const result = await TestStep.run({
|
144
|
+
...contextWithPR,
|
145
|
+
inputs: {},
|
146
|
+
})
|
147
|
+
expect(result).toEqual({ isActive: true })
|
148
|
+
})
|
149
|
+
})
|
@@ -0,0 +1,232 @@
|
|
1
|
+
/**
|
2
|
+
* Type-safe workflow step framework for GitHub Actions
|
3
|
+
*/
|
4
|
+
|
5
|
+
// import type { Context } from '@actions/github/lib/context.ts'
|
6
|
+
import type { GitHub } from '@actions/github/lib/utils.ts'
|
7
|
+
import { z } from 'zod/v4'
|
8
|
+
import type { GitController } from './git-controller.ts'
|
9
|
+
import type { PullRequestController } from './pr-controller.ts'
|
10
|
+
import type { Context, ContextSchema as RealContextSchema } from './schemas/context.ts'
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Arguments passed to the step's run function.
|
14
|
+
*
|
15
|
+
* @template $Inputs - The validated input values based on your inputs schema
|
16
|
+
* @template $Context - The GitHub Actions context (validated if context schema provided)
|
17
|
+
*/
|
18
|
+
export interface Args<$Inputs extends Inputs = Inputs, $Context = Context> {
|
19
|
+
/** GitHub Actions core utilities for logging, setting outputs, etc. */
|
20
|
+
core: typeof import('@actions/core')
|
21
|
+
|
22
|
+
/** GitHub Actions context containing event payload, repo info, etc. */
|
23
|
+
context: $Context
|
24
|
+
|
25
|
+
/** Validated input values passed to the step */
|
26
|
+
inputs: $Inputs
|
27
|
+
|
28
|
+
/** Authenticated Octokit instance for GitHub API operations */
|
29
|
+
github: InstanceType<typeof GitHub>
|
30
|
+
|
31
|
+
/** zx's $ function for executing shell commands */
|
32
|
+
$: typeof import('zx').$
|
33
|
+
|
34
|
+
/** Node.js fs/promises module for file operations */
|
35
|
+
fs: typeof import('node:fs/promises')
|
36
|
+
|
37
|
+
/** PR controller for pull request operations (comment, review, etc.) */
|
38
|
+
pr: PullRequestController
|
39
|
+
|
40
|
+
/** Git controller for git operations (commit, push, etc.) without subprocess details */
|
41
|
+
git: GitController
|
42
|
+
}
|
43
|
+
|
44
|
+
export type Outputs = object
|
45
|
+
|
46
|
+
export type Inputs = object
|
47
|
+
|
48
|
+
type InputsSchema = z.ZodObject
|
49
|
+
|
50
|
+
type OutputsSchema = z.ZodObject
|
51
|
+
|
52
|
+
// This is a loose type because working with sub/sup schema types is complex, maybe not even workable, unclear, and not worth the effort
|
53
|
+
type ContextSchema = z.Schema
|
54
|
+
|
55
|
+
// Export the full step definition for runner
|
56
|
+
export interface Step<
|
57
|
+
$InputsSchema extends InputsSchema = InputsSchema,
|
58
|
+
$OutputsSchema extends OutputsSchema = OutputsSchema,
|
59
|
+
$ContextSchema extends ContextSchema = ContextSchema,
|
60
|
+
> {
|
61
|
+
definition: Definition<
|
62
|
+
$InputsSchema,
|
63
|
+
$OutputsSchema,
|
64
|
+
$ContextSchema
|
65
|
+
>
|
66
|
+
run: Runner<
|
67
|
+
z.output<$InputsSchema>,
|
68
|
+
z.output<$OutputsSchema>,
|
69
|
+
z.output<$ContextSchema>
|
70
|
+
>
|
71
|
+
}
|
72
|
+
|
73
|
+
export type Runner<
|
74
|
+
$Inputs extends Inputs = Inputs,
|
75
|
+
$Outputs extends Outputs = Outputs,
|
76
|
+
$Context = Context,
|
77
|
+
> = (
|
78
|
+
context: Args<$Inputs, $Context>,
|
79
|
+
) => Promise<$Outputs>
|
80
|
+
|
81
|
+
// Generic workflow step definition
|
82
|
+
export interface Definition<
|
83
|
+
$InputsSchema extends InputsSchema,
|
84
|
+
$OutputsSchema extends OutputsSchema,
|
85
|
+
$ContextSchema extends ContextSchema,
|
86
|
+
> {
|
87
|
+
description?: string
|
88
|
+
name?: string
|
89
|
+
inputsSchema?: $InputsSchema
|
90
|
+
outputsSchema?: $OutputsSchema
|
91
|
+
contextSchema?: $ContextSchema
|
92
|
+
}
|
93
|
+
|
94
|
+
// Generic workflow step definition
|
95
|
+
export interface CreateInput<
|
96
|
+
$InputsSchema extends InputsSchema,
|
97
|
+
$OutputsSchema extends OutputsSchema,
|
98
|
+
$ContextSchema extends z.Schema,
|
99
|
+
> {
|
100
|
+
description?: string
|
101
|
+
name?: string
|
102
|
+
inputs?: $InputsSchema
|
103
|
+
outputs?: $OutputsSchema
|
104
|
+
context?: $ContextSchema
|
105
|
+
run: (
|
106
|
+
args: Args<z.output<$InputsSchema>, z.output<$ContextSchema>>,
|
107
|
+
// todo: Obj.isEmpty ...
|
108
|
+
) => Promise<{} extends z.Infer<$OutputsSchema> ? void : z.Infer<$OutputsSchema>>
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Create a type-safe GitHub Actions workflow step with runtime validation.
|
113
|
+
*
|
114
|
+
* This is the main entry point for defining custom workflow steps that can be executed
|
115
|
+
* by the GitHub Actions runner. It provides:
|
116
|
+
* - Type-safe inputs/outputs with Zod schema validation
|
117
|
+
* - Automatic GitHub Actions output handling (both individual outputs and bundled JSON)
|
118
|
+
* - Context validation to ensure steps run in the correct workflow events
|
119
|
+
* - Integration with GitHub API via Octokit
|
120
|
+
* - Built-in error handling and logging
|
121
|
+
*
|
122
|
+
* @example Basic step with inputs and outputs
|
123
|
+
* ```typescript
|
124
|
+
* import { z } from 'zod'
|
125
|
+
* import { GitHubActions } from '#lib/github-actions'
|
126
|
+
*
|
127
|
+
* export default GitHubActions.createStep({
|
128
|
+
* name: 'my-step',
|
129
|
+
* description: 'Processes some data and returns results',
|
130
|
+
* inputs: z.object({
|
131
|
+
* message: z.string(),
|
132
|
+
* count: z.number().optional().default(1),
|
133
|
+
* }),
|
134
|
+
* outputs: z.object({
|
135
|
+
* result: z.string(),
|
136
|
+
* processed: z.boolean(),
|
137
|
+
* }),
|
138
|
+
* async run({ inputs, core }) {
|
139
|
+
* core.info(`Processing: ${inputs.message}`)
|
140
|
+
*
|
141
|
+
* return {
|
142
|
+
* result: inputs.message.toUpperCase(),
|
143
|
+
* processed: true,
|
144
|
+
* }
|
145
|
+
* }
|
146
|
+
* })
|
147
|
+
* ```
|
148
|
+
*
|
149
|
+
* @example Step with specific context requirements
|
150
|
+
* ```typescript
|
151
|
+
* export default GitHubActions.createStep({
|
152
|
+
* name: 'pr-only-step',
|
153
|
+
* description: 'This step only runs on pull requests',
|
154
|
+
* context: GitHubActions.PullRequestContext,
|
155
|
+
* outputs: z.object({
|
156
|
+
* pr_number: z.number(),
|
157
|
+
* }),
|
158
|
+
* async run({ context, core }) {
|
159
|
+
* const prNumber = context.payload.pull_request.number
|
160
|
+
* core.info(`Running on PR #${prNumber}`)
|
161
|
+
*
|
162
|
+
* return { pr_number: prNumber }
|
163
|
+
* }
|
164
|
+
* })
|
165
|
+
* ```
|
166
|
+
*
|
167
|
+
* @example Using the GitHub API
|
168
|
+
* ```typescript
|
169
|
+
* export default GitHubActions.createStep({
|
170
|
+
* name: 'create-issue',
|
171
|
+
* description: 'Creates a GitHub issue',
|
172
|
+
* inputs: z.object({
|
173
|
+
* title: z.string(),
|
174
|
+
* body: z.string(),
|
175
|
+
* }),
|
176
|
+
* outputs: z.object({
|
177
|
+
* issue_number: z.number(),
|
178
|
+
* issue_url: z.string(),
|
179
|
+
* }),
|
180
|
+
* async run({ inputs, github, context }) {
|
181
|
+
* const issue = await github.rest.issues.create({
|
182
|
+
* owner: context.repo.owner,
|
183
|
+
* repo: context.repo.repo,
|
184
|
+
* title: inputs.title,
|
185
|
+
* body: inputs.body,
|
186
|
+
* })
|
187
|
+
*
|
188
|
+
* return {
|
189
|
+
* issue_number: issue.data.number,
|
190
|
+
* issue_url: issue.data.html_url,
|
191
|
+
* }
|
192
|
+
* }
|
193
|
+
* })
|
194
|
+
* ```
|
195
|
+
*
|
196
|
+
* @param input - Step configuration object
|
197
|
+
* @param input.name - Unique identifier for the step (used in logging and debugging)
|
198
|
+
* @param input.description - Human-readable description of what the step does
|
199
|
+
* @param input.inputs - Optional Zod schema for validating step inputs
|
200
|
+
* @param input.outputs - Optional Zod schema for validating step outputs
|
201
|
+
* @param input.context - Optional Zod schema for validating GitHub Actions context (event type)
|
202
|
+
* @param input.run - Async function that implements the step logic
|
203
|
+
*
|
204
|
+
* @returns A Step object that can be executed by the GitHub Actions runner
|
205
|
+
*
|
206
|
+
* @remarks
|
207
|
+
* - All outputs are automatically set as GitHub Actions outputs
|
208
|
+
* - Boolean outputs are properly handled (use fromJSON in workflows)
|
209
|
+
* - A special 'json' output contains all outputs bundled together
|
210
|
+
* - The runner provides extensive logging and error handling
|
211
|
+
* - Steps can access PR controller for pull request operations
|
212
|
+
* - The `$` from zx is available for shell commands
|
213
|
+
*/
|
214
|
+
export function createStep<
|
215
|
+
$InputsSchema extends InputsSchema,
|
216
|
+
$OutputsSchema extends OutputsSchema,
|
217
|
+
$ContextSchema extends ContextSchema = RealContextSchema,
|
218
|
+
>(
|
219
|
+
input: CreateInput<$InputsSchema, $OutputsSchema, $ContextSchema>,
|
220
|
+
): Step<$InputsSchema, $OutputsSchema, $ContextSchema> {
|
221
|
+
const { run, inputs, outputs, context, ...rest } = input
|
222
|
+
const definition: Definition<$InputsSchema, $OutputsSchema, $ContextSchema> = {
|
223
|
+
...rest,
|
224
|
+
inputsSchema: inputs,
|
225
|
+
outputsSchema: outputs,
|
226
|
+
contextSchema: context,
|
227
|
+
}
|
228
|
+
return {
|
229
|
+
definition,
|
230
|
+
run,
|
231
|
+
} as any
|
232
|
+
}
|
package/src/lib/helpers.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Manifest } from '@wollybeard/kit'
|
1
|
+
import { Err, Manifest } from '@wollybeard/kit'
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Check if a project has a package installed by examining its package.json
|
@@ -9,8 +9,9 @@ export async function checkIsProjectHasPackageInstalled(
|
|
9
9
|
): Promise<boolean> {
|
10
10
|
const packageJson = await Manifest.resource.read(projectRoot)
|
11
11
|
|
12
|
-
if (
|
13
|
-
return false
|
12
|
+
if (Err.is(packageJson)) {
|
13
|
+
if (packageJson._tag === 'ResourceErrorNotFound') return false
|
14
|
+
throw packageJson
|
14
15
|
}
|
15
16
|
|
16
17
|
// Check if React is in dependencies or devDependencies
|
@@ -0,0 +1,115 @@
|
|
1
|
+
import { Ts } from '@wollybeard/kit'
|
2
|
+
import { objFilter, ObjOmit, ObjPick, objPolicyFilter } from './kit-temp.js'
|
3
|
+
import type { ObjPolicyFilter } from './kit-temp.js'
|
4
|
+
|
5
|
+
// Test object for all tests
|
6
|
+
type TestObj = { a: string; b: number; c: boolean; d: string[] }
|
7
|
+
declare const testObj: TestObj
|
8
|
+
|
9
|
+
// Test 1: objPolicyFilter with allow mode
|
10
|
+
{
|
11
|
+
const result = objPolicyFilter('allow', testObj, ['a', 'c'] as const)
|
12
|
+
Ts.assertEqual<{ a: string; c: boolean }>()(result)
|
13
|
+
}
|
14
|
+
|
15
|
+
// Test 2: objPolicyFilter with deny mode
|
16
|
+
{
|
17
|
+
const result = objPolicyFilter('deny', testObj, ['a', 'c'] as const)
|
18
|
+
Ts.assertEqual<{ b: number; d: string[] }>()(result)
|
19
|
+
}
|
20
|
+
|
21
|
+
// Test 3: objFilter returns Partial<T>
|
22
|
+
{
|
23
|
+
const result = objFilter(testObj, (key, value) => value !== 'hello')
|
24
|
+
Ts.assertEqual<Partial<TestObj>>()(result)
|
25
|
+
|
26
|
+
// All properties are optional
|
27
|
+
Ts.assertSub<typeof result.a>()(undefined)
|
28
|
+
Ts.assertSub<typeof result.b>()(undefined)
|
29
|
+
Ts.assertSub<typeof result.c>()(undefined)
|
30
|
+
Ts.assertSub<typeof result.d>()(undefined)
|
31
|
+
}
|
32
|
+
|
33
|
+
// Test 4: ObjPick type inference
|
34
|
+
{
|
35
|
+
const result = ObjPick(testObj, ['a', 'c'] as const)
|
36
|
+
Ts.assertEqual<{ a: string; c: boolean }>()(result)
|
37
|
+
}
|
38
|
+
|
39
|
+
// Test 5: ObjOmit type inference
|
40
|
+
{
|
41
|
+
const result = ObjOmit(testObj, ['a', 'c'] as const)
|
42
|
+
Ts.assertEqual<{ b: number; d: string[] }>()(result)
|
43
|
+
}
|
44
|
+
|
45
|
+
// Test 6: ObjPolicyFilter type-level function
|
46
|
+
{
|
47
|
+
type Allow = ObjPolicyFilter<TestObj, 'a' | 'c', 'allow'>
|
48
|
+
type _TestAllow = Ts.AssertEqual<Allow, { a: string; c: boolean }>
|
49
|
+
|
50
|
+
type Deny = ObjPolicyFilter<TestObj, 'a' | 'c', 'deny'>
|
51
|
+
type _TestDeny = Ts.AssertEqual<Deny, { b: number; d: string[] }>
|
52
|
+
|
53
|
+
type AllowEmpty = ObjPolicyFilter<TestObj, never, 'allow'>
|
54
|
+
type _TestAllowEmpty = Ts.AssertEqual<AllowEmpty, {}>
|
55
|
+
|
56
|
+
type DenyEmpty = ObjPolicyFilter<TestObj, never, 'deny'>
|
57
|
+
type _TestDenyEmpty = Ts.AssertEqual<DenyEmpty, TestObj>
|
58
|
+
}
|
59
|
+
|
60
|
+
// Test 7: Edge cases
|
61
|
+
{
|
62
|
+
// Empty object
|
63
|
+
const empty = {}
|
64
|
+
const allowEmpty = objPolicyFilter('allow', empty, [])
|
65
|
+
const denyEmpty = objPolicyFilter('deny', empty, [])
|
66
|
+
const filterEmpty = objFilter(empty, () => true)
|
67
|
+
|
68
|
+
Ts.assertEqual<{}>()(allowEmpty)
|
69
|
+
Ts.assertEqual<{}>()(denyEmpty)
|
70
|
+
Ts.assertEqual<{}>()(filterEmpty)
|
71
|
+
|
72
|
+
// Single property object
|
73
|
+
const single = { a: 1 }
|
74
|
+
const allowSingle = objPolicyFilter('allow', single, ['a'] as const)
|
75
|
+
const denySingle = objPolicyFilter('deny', single, ['a'] as const)
|
76
|
+
const filterSingle = objFilter(single, () => true)
|
77
|
+
|
78
|
+
Ts.assertEqual<{ a: number }>()(allowSingle)
|
79
|
+
Ts.assertEqual<{}>()(denySingle)
|
80
|
+
Ts.assertEqual<{ a?: number }>()(filterSingle)
|
81
|
+
}
|
82
|
+
|
83
|
+
// Test 8: Complex nested object
|
84
|
+
{
|
85
|
+
type ComplexObj = {
|
86
|
+
nested: { a: string; b: number }
|
87
|
+
array: string[]
|
88
|
+
optional?: boolean
|
89
|
+
readonly ro: string
|
90
|
+
}
|
91
|
+
const complexObj = {} as ComplexObj
|
92
|
+
|
93
|
+
const picked = objPolicyFilter('allow', complexObj, ['nested', 'optional'] as const)
|
94
|
+
Ts.assertEqual<{ nested: { a: string; b: number }; optional?: boolean }>()(picked)
|
95
|
+
|
96
|
+
const omitted = objPolicyFilter('deny', complexObj, ['nested', 'optional'] as const)
|
97
|
+
Ts.assertEqual<{ array: string[]; readonly ro: string }>()(omitted)
|
98
|
+
|
99
|
+
const filtered = objFilter(complexObj, (key) => key !== 'array')
|
100
|
+
Ts.assertEqual<Partial<ComplexObj>>()(filtered)
|
101
|
+
}
|
102
|
+
|
103
|
+
// Test 9: Keys parameter type inference
|
104
|
+
{
|
105
|
+
// With const assertion
|
106
|
+
const keys1 = ['a', 'c'] as const
|
107
|
+
const result1 = objPolicyFilter('allow', testObj, keys1)
|
108
|
+
Ts.assertEqual<{ a: string; c: boolean }>()(result1)
|
109
|
+
|
110
|
+
// Without const assertion (wider type)
|
111
|
+
const keys2: (keyof TestObj)[] = ['a', 'c']
|
112
|
+
const result2 = objPolicyFilter('allow', testObj, keys2)
|
113
|
+
// Result is a union of all possible picks
|
114
|
+
type Result2 = typeof result2 // Pick<TestObj, keyof TestObj>
|
115
|
+
}
|
@@ -0,0 +1,127 @@
|
|
1
|
+
import * as fc from 'fast-check'
|
2
|
+
import { describe, expect, test } from 'vitest'
|
3
|
+
import { objFilter, ObjOmit, ObjPick, objPolicyFilter } from './kit-temp.js'
|
4
|
+
|
5
|
+
describe('objPolicyFilter', () => {
|
6
|
+
const testObj = { a: 1, b: 2, c: 3, d: 4 }
|
7
|
+
|
8
|
+
test('allow mode picks specified keys', () => {
|
9
|
+
expect(objPolicyFilter('allow', testObj, ['a', 'c'])).toEqual({ a: 1, c: 3 })
|
10
|
+
expect(objPolicyFilter('allow', testObj, [])).toEqual({})
|
11
|
+
expect(objPolicyFilter('allow', testObj, ['a', 'z'] as any)).toEqual({ a: 1 })
|
12
|
+
})
|
13
|
+
|
14
|
+
test('deny mode omits specified keys', () => {
|
15
|
+
expect(objPolicyFilter('deny', testObj, ['a', 'c'])).toEqual({ b: 2, d: 4 })
|
16
|
+
expect(objPolicyFilter('deny', testObj, [])).toEqual(testObj)
|
17
|
+
expect(objPolicyFilter('deny', testObj, ['z'] as any)).toEqual(testObj)
|
18
|
+
})
|
19
|
+
|
20
|
+
test('preserves undefined values', () => {
|
21
|
+
const obj = { a: 1, b: undefined, c: 3 }
|
22
|
+
expect(objPolicyFilter('allow', obj, ['a', 'b'])).toEqual({ a: 1, b: undefined })
|
23
|
+
})
|
24
|
+
})
|
25
|
+
|
26
|
+
describe('objFilter', () => {
|
27
|
+
const testObj = { a: 1, b: 2, c: 3, d: 4 }
|
28
|
+
|
29
|
+
test('filters by predicates', () => {
|
30
|
+
// By value
|
31
|
+
expect(objFilter(testObj, (k, v) => v > 2)).toEqual({ c: 3, d: 4 })
|
32
|
+
|
33
|
+
// By key
|
34
|
+
expect(objFilter(testObj, k => k === 'a' || k === 'c')).toEqual({ a: 1, c: 3 })
|
35
|
+
|
36
|
+
// By full object context
|
37
|
+
expect(objFilter(testObj, (k, v, obj) => {
|
38
|
+
const avg = Object.values(obj).reduce((a, b) => a + b, 0) / Object.keys(obj).length
|
39
|
+
return v < avg
|
40
|
+
})).toEqual({ a: 1, b: 2 })
|
41
|
+
})
|
42
|
+
|
43
|
+
test('edge cases', () => {
|
44
|
+
expect(objFilter(testObj, () => false)).toEqual({})
|
45
|
+
expect(objFilter(testObj, () => true)).toEqual(testObj)
|
46
|
+
expect(objFilter({}, () => true)).toEqual({})
|
47
|
+
})
|
48
|
+
})
|
49
|
+
|
50
|
+
describe('ObjPick and ObjOmit', () => {
|
51
|
+
test('are aliases for objPolicyFilter', () => {
|
52
|
+
const obj = { a: 1, b: 2, c: 3 }
|
53
|
+
const keys = ['a', 'c'] as const
|
54
|
+
|
55
|
+
expect(ObjPick(obj, keys)).toEqual(objPolicyFilter('allow', obj, keys))
|
56
|
+
expect(ObjOmit(obj, keys)).toEqual(objPolicyFilter('deny', obj, keys))
|
57
|
+
})
|
58
|
+
})
|
59
|
+
|
60
|
+
describe('property-based tests', () => {
|
61
|
+
test('objPolicyFilter allow/deny are complementary', () => {
|
62
|
+
fc.assert(
|
63
|
+
fc.property(
|
64
|
+
fc.object(),
|
65
|
+
fc.array(fc.string()),
|
66
|
+
(obj, keys) => {
|
67
|
+
const allowed = objPolicyFilter('allow', obj, keys)
|
68
|
+
const denied = objPolicyFilter('deny', obj, keys)
|
69
|
+
|
70
|
+
// Every key in obj is either in allowed or denied, never both
|
71
|
+
Object.keys(obj).forEach(key => {
|
72
|
+
const inAllowed = Object.prototype.hasOwnProperty.call(allowed, key)
|
73
|
+
const inDenied = Object.prototype.hasOwnProperty.call(denied, key)
|
74
|
+
expect(inAllowed).toBe(!inDenied)
|
75
|
+
})
|
76
|
+
|
77
|
+
// Combined they reconstruct the original object
|
78
|
+
expect({ ...allowed, ...denied }).toEqual(obj)
|
79
|
+
},
|
80
|
+
),
|
81
|
+
)
|
82
|
+
})
|
83
|
+
|
84
|
+
test('objFilter preserves values unchanged', () => {
|
85
|
+
fc.assert(
|
86
|
+
fc.property(
|
87
|
+
fc.object(),
|
88
|
+
(obj) => {
|
89
|
+
const filtered = objFilter(obj, () => true)
|
90
|
+
expect(filtered).toEqual(obj)
|
91
|
+
|
92
|
+
// Values are the same reference
|
93
|
+
Object.keys(filtered).forEach(key => {
|
94
|
+
expect(filtered[key]).toBe(obj[key])
|
95
|
+
})
|
96
|
+
},
|
97
|
+
),
|
98
|
+
)
|
99
|
+
})
|
100
|
+
|
101
|
+
test('objPolicyFilter is immutable', () => {
|
102
|
+
fc.assert(
|
103
|
+
fc.property(
|
104
|
+
fc.object(),
|
105
|
+
fc.array(fc.string()),
|
106
|
+
fc.oneof(fc.constant('allow' as const), fc.constant('deny' as const)),
|
107
|
+
(obj, keys, mode) => {
|
108
|
+
const original = { ...obj }
|
109
|
+
objPolicyFilter(mode, obj, keys)
|
110
|
+
expect(obj).toEqual(original)
|
111
|
+
},
|
112
|
+
),
|
113
|
+
)
|
114
|
+
})
|
115
|
+
|
116
|
+
test('empty keys behavior', () => {
|
117
|
+
fc.assert(
|
118
|
+
fc.property(
|
119
|
+
fc.object(),
|
120
|
+
(obj) => {
|
121
|
+
expect(objPolicyFilter('allow', obj, [])).toEqual({})
|
122
|
+
expect(objPolicyFilter('deny', obj, [])).toEqual(obj)
|
123
|
+
},
|
124
|
+
),
|
125
|
+
)
|
126
|
+
})
|
127
|
+
})
|