gazetta 0.7.0 → 0.8.0
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/admin-dist/assets/index-CBeq0rRb.js +693 -0
- package/admin-dist/assets/index-Dtg1dTZQ.css +1 -0
- package/admin-dist/assets/rolldown-runtime-BYbx6iT9.js +1 -0
- package/admin-dist/assets/{vendor-primevue-C0Q_YTCb.js → vendor-primevue-CBGHkaXv.js} +183 -39
- package/admin-dist/assets/{vendor-react-BipDVGow.js → vendor-react-BdW_kNCG.js} +2 -2
- package/admin-dist/assets/vendor-rjsf-lN2SztQt.js +33 -0
- package/admin-dist/assets/vendor-tiptap-C36yDquB.js +141 -0
- package/admin-dist/assets/vendor-vue-Bt5uR1VW.js +1 -0
- package/admin-dist/assets/workbox-window.prod.es5-DGMtIXHc.js +2 -0
- package/admin-dist/index.html +8 -8
- package/admin-dist/sw.js +1 -0
- package/dist/admin-api/archived-name-conflict.d.ts +31 -0
- package/dist/admin-api/archived-name-conflict.d.ts.map +1 -0
- package/dist/admin-api/archived-name-conflict.js +226 -0
- package/dist/admin-api/archived-name-conflict.js.map +1 -0
- package/dist/admin-api/cache-stats-logger.d.ts +83 -0
- package/dist/admin-api/cache-stats-logger.d.ts.map +1 -0
- package/dist/admin-api/cache-stats-logger.js +59 -0
- package/dist/admin-api/cache-stats-logger.js.map +1 -0
- package/dist/admin-api/hook-audit-emitter.d.ts +38 -0
- package/dist/admin-api/hook-audit-emitter.d.ts.map +1 -0
- package/dist/admin-api/hook-audit-emitter.js +21 -0
- package/dist/admin-api/hook-audit-emitter.js.map +1 -0
- package/dist/admin-api/index.d.ts +84 -0
- package/dist/admin-api/index.d.ts.map +1 -1
- package/dist/admin-api/index.js +254 -9
- package/dist/admin-api/index.js.map +1 -1
- package/dist/admin-api/middleware/audit.d.ts +25 -0
- package/dist/admin-api/middleware/audit.d.ts.map +1 -0
- package/dist/admin-api/middleware/audit.js +65 -0
- package/dist/admin-api/middleware/audit.js.map +1 -0
- package/dist/admin-api/middleware/capability.d.ts +8 -0
- package/dist/admin-api/middleware/capability.d.ts.map +1 -0
- package/dist/admin-api/middleware/capability.js +65 -0
- package/dist/admin-api/middleware/capability.js.map +1 -0
- package/dist/admin-api/middleware/principal.d.ts +18 -0
- package/dist/admin-api/middleware/principal.d.ts.map +1 -0
- package/dist/admin-api/middleware/principal.js +128 -0
- package/dist/admin-api/middleware/principal.js.map +1 -0
- package/dist/admin-api/routes/archive-review.d.ts +80 -0
- package/dist/admin-api/routes/archive-review.d.ts.map +1 -0
- package/dist/admin-api/routes/archive-review.js +70 -0
- package/dist/admin-api/routes/archive-review.js.map +1 -0
- package/dist/admin-api/routes/archive.d.ts +145 -0
- package/dist/admin-api/routes/archive.d.ts.map +1 -0
- package/dist/admin-api/routes/archive.js +540 -0
- package/dist/admin-api/routes/archive.js.map +1 -0
- package/dist/admin-api/routes/assets.d.ts +6 -1
- package/dist/admin-api/routes/assets.d.ts.map +1 -1
- package/dist/admin-api/routes/assets.js +167 -14
- package/dist/admin-api/routes/assets.js.map +1 -1
- package/dist/admin-api/routes/audit.d.ts +71 -0
- package/dist/admin-api/routes/audit.d.ts.map +1 -0
- package/dist/admin-api/routes/audit.js +178 -0
- package/dist/admin-api/routes/audit.js.map +1 -0
- package/dist/admin-api/routes/compare.d.ts.map +1 -1
- package/dist/admin-api/routes/compare.js +3 -2
- package/dist/admin-api/routes/compare.js.map +1 -1
- package/dist/admin-api/routes/fields.d.ts.map +1 -1
- package/dist/admin-api/routes/fields.js +2 -1
- package/dist/admin-api/routes/fields.js.map +1 -1
- package/dist/admin-api/routes/fragments.d.ts +13 -1
- package/dist/admin-api/routes/fragments.d.ts.map +1 -1
- package/dist/admin-api/routes/fragments.js +127 -92
- package/dist/admin-api/routes/fragments.js.map +1 -1
- package/dist/admin-api/routes/health.d.ts +60 -0
- package/dist/admin-api/routes/health.d.ts.map +1 -0
- package/dist/admin-api/routes/health.js +65 -0
- package/dist/admin-api/routes/health.js.map +1 -0
- package/dist/admin-api/routes/history.d.ts +2 -1
- package/dist/admin-api/routes/history.d.ts.map +1 -1
- package/dist/admin-api/routes/history.js +26 -4
- package/dist/admin-api/routes/history.js.map +1 -1
- package/dist/admin-api/routes/pages.d.ts +20 -1
- package/dist/admin-api/routes/pages.d.ts.map +1 -1
- package/dist/admin-api/routes/pages.js +157 -117
- package/dist/admin-api/routes/pages.js.map +1 -1
- package/dist/admin-api/routes/preview.d.ts.map +1 -1
- package/dist/admin-api/routes/preview.js +56 -17
- package/dist/admin-api/routes/preview.js.map +1 -1
- package/dist/admin-api/routes/publish.d.ts +19 -1
- package/dist/admin-api/routes/publish.d.ts.map +1 -1
- package/dist/admin-api/routes/publish.js +508 -92
- package/dist/admin-api/routes/publish.js.map +1 -1
- package/dist/admin-api/routes/rename.d.ts +62 -0
- package/dist/admin-api/routes/rename.d.ts.map +1 -0
- package/dist/admin-api/routes/rename.js +366 -0
- package/dist/admin-api/routes/rename.js.map +1 -0
- package/dist/admin-api/routes/site.d.ts.map +1 -1
- package/dist/admin-api/routes/site.js +6 -18
- package/dist/admin-api/routes/site.js.map +1 -1
- package/dist/admin-api/routes/system.d.ts +23 -0
- package/dist/admin-api/routes/system.d.ts.map +1 -0
- package/dist/admin-api/routes/system.js +115 -0
- package/dist/admin-api/routes/system.js.map +1 -0
- package/dist/admin-api/routes/templates.d.ts +11 -1
- package/dist/admin-api/routes/templates.d.ts.map +1 -1
- package/dist/admin-api/routes/templates.js +36 -3
- package/dist/admin-api/routes/templates.js.map +1 -1
- package/dist/admin-api/routes/validation.d.ts +47 -0
- package/dist/admin-api/routes/validation.d.ts.map +1 -0
- package/dist/admin-api/routes/validation.js +120 -0
- package/dist/admin-api/routes/validation.js.map +1 -0
- package/dist/admin-api/schemas/archive.d.ts +124 -0
- package/dist/admin-api/schemas/archive.d.ts.map +1 -0
- package/dist/admin-api/schemas/archive.js +93 -0
- package/dist/admin-api/schemas/archive.js.map +1 -0
- package/dist/admin-api/schemas/assets.d.ts +16 -0
- package/dist/admin-api/schemas/assets.d.ts.map +1 -1
- package/dist/admin-api/schemas/assets.js +15 -0
- package/dist/admin-api/schemas/assets.js.map +1 -1
- package/dist/admin-api/schemas/audit.d.ts +175 -0
- package/dist/admin-api/schemas/audit.d.ts.map +1 -0
- package/dist/admin-api/schemas/audit.js +91 -0
- package/dist/admin-api/schemas/audit.js.map +1 -0
- package/dist/admin-api/schemas/error.d.ts +94 -0
- package/dist/admin-api/schemas/error.d.ts.map +1 -0
- package/dist/admin-api/schemas/error.js +79 -0
- package/dist/admin-api/schemas/error.js.map +1 -0
- package/dist/admin-api/schemas/fragments.d.ts +2 -0
- package/dist/admin-api/schemas/fragments.d.ts.map +1 -1
- package/dist/admin-api/schemas/fragments.js +4 -0
- package/dist/admin-api/schemas/fragments.js.map +1 -1
- package/dist/admin-api/schemas/index.d.ts +8 -0
- package/dist/admin-api/schemas/index.d.ts.map +1 -1
- package/dist/admin-api/schemas/index.js +8 -0
- package/dist/admin-api/schemas/index.js.map +1 -1
- package/dist/admin-api/schemas/pages.d.ts +2 -0
- package/dist/admin-api/schemas/pages.d.ts.map +1 -1
- package/dist/admin-api/schemas/pages.js +11 -0
- package/dist/admin-api/schemas/pages.js.map +1 -1
- package/dist/admin-api/schemas/rename.d.ts +77 -0
- package/dist/admin-api/schemas/rename.d.ts.map +1 -0
- package/dist/admin-api/schemas/rename.js +75 -0
- package/dist/admin-api/schemas/rename.js.map +1 -0
- package/dist/admin-api/schemas/site.d.ts +3 -2
- package/dist/admin-api/schemas/site.d.ts.map +1 -1
- package/dist/admin-api/schemas/site.js +3 -2
- package/dist/admin-api/schemas/site.js.map +1 -1
- package/dist/admin-api/schemas/system.d.ts +28 -0
- package/dist/admin-api/schemas/system.d.ts.map +1 -0
- package/dist/admin-api/schemas/system.js +35 -0
- package/dist/admin-api/schemas/system.js.map +1 -0
- package/dist/admin-api/schemas/targets.d.ts +55 -0
- package/dist/admin-api/schemas/targets.d.ts.map +1 -1
- package/dist/admin-api/schemas/targets.js +46 -0
- package/dist/admin-api/schemas/targets.js.map +1 -1
- package/dist/admin-api/schemas/templates.d.ts +54 -0
- package/dist/admin-api/schemas/templates.d.ts.map +1 -1
- package/dist/admin-api/schemas/templates.js +21 -0
- package/dist/admin-api/schemas/templates.js.map +1 -1
- package/dist/admin-api/schemas/validation.d.ts +101 -0
- package/dist/admin-api/schemas/validation.d.ts.map +1 -0
- package/dist/admin-api/schemas/validation.js +57 -0
- package/dist/admin-api/schemas/validation.js.map +1 -0
- package/dist/admin-api/source-context.d.ts +66 -10
- package/dist/admin-api/source-context.d.ts.map +1 -1
- package/dist/admin-api/source-context.js +43 -5
- package/dist/admin-api/source-context.js.map +1 -1
- package/dist/ai/adapter-scaffold.d.ts +63 -0
- package/dist/ai/adapter-scaffold.d.ts.map +1 -0
- package/dist/ai/adapter-scaffold.js +89 -0
- package/dist/ai/adapter-scaffold.js.map +1 -0
- package/dist/ai/compose-prompt.d.ts +50 -0
- package/dist/ai/compose-prompt.d.ts.map +1 -0
- package/dist/ai/compose-prompt.js +49 -0
- package/dist/ai/compose-prompt.js.map +1 -0
- package/dist/ai/errors.d.ts +65 -0
- package/dist/ai/errors.d.ts.map +1 -0
- package/dist/ai/errors.js +59 -0
- package/dist/ai/errors.js.map +1 -0
- package/dist/ai/index.d.ts +17 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +16 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/provider.d.ts +76 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +13 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/ai/refusal.d.ts +50 -0
- package/dist/ai/refusal.d.ts.map +1 -0
- package/dist/ai/refusal.js +100 -0
- package/dist/ai/refusal.js.map +1 -0
- package/dist/ai/vision-prep.d.ts +32 -0
- package/dist/ai/vision-prep.d.ts.map +1 -0
- package/dist/ai/vision-prep.js +113 -0
- package/dist/ai/vision-prep.js.map +1 -0
- package/dist/alt/adapter.d.ts +140 -0
- package/dist/alt/adapter.d.ts.map +1 -0
- package/dist/alt/adapter.js +7 -0
- package/dist/alt/adapter.js.map +1 -0
- package/dist/alt/anthropic.d.ts +63 -0
- package/dist/alt/anthropic.d.ts.map +1 -0
- package/dist/alt/anthropic.js +147 -0
- package/dist/alt/anthropic.js.map +1 -0
- package/dist/alt/config.d.ts +67 -0
- package/dist/alt/config.d.ts.map +1 -0
- package/dist/alt/config.js +41 -0
- package/dist/alt/config.js.map +1 -0
- package/dist/alt/factory.d.ts +19 -0
- package/dist/alt/factory.d.ts.map +1 -0
- package/dist/alt/factory.js +69 -0
- package/dist/alt/factory.js.map +1 -0
- package/dist/alt/null-adapter.d.ts +3 -0
- package/dist/alt/null-adapter.d.ts.map +1 -0
- package/dist/alt/null-adapter.js +43 -0
- package/dist/alt/null-adapter.js.map +1 -0
- package/dist/alt/ollama.d.ts +40 -0
- package/dist/alt/ollama.d.ts.map +1 -0
- package/dist/alt/ollama.js +139 -0
- package/dist/alt/ollama.js.map +1 -0
- package/dist/alt/openai.d.ts +46 -0
- package/dist/alt/openai.d.ts.map +1 -0
- package/dist/alt/openai.js +118 -0
- package/dist/alt/openai.js.map +1 -0
- package/dist/alt/prompt-policies.d.ts +79 -0
- package/dist/alt/prompt-policies.d.ts.map +1 -0
- package/dist/alt/prompt-policies.js +67 -0
- package/dist/alt/prompt-policies.js.map +1 -0
- package/dist/alt/route-handler.d.ts +56 -0
- package/dist/alt/route-handler.d.ts.map +1 -0
- package/dist/alt/route-handler.js +122 -0
- package/dist/alt/route-handler.js.map +1 -0
- package/dist/alt/suggester.d.ts +57 -0
- package/dist/alt/suggester.d.ts.map +1 -0
- package/dist/alt/suggester.js +133 -0
- package/dist/alt/suggester.js.map +1 -0
- package/dist/app.js +1 -1
- package/dist/app.js.map +1 -1
- package/dist/archive-aliases.d.ts +79 -0
- package/dist/archive-aliases.d.ts.map +1 -0
- package/dist/archive-aliases.js +60 -0
- package/dist/archive-aliases.js.map +1 -0
- package/dist/archive-helpers.d.ts +73 -0
- package/dist/archive-helpers.d.ts.map +1 -0
- package/dist/archive-helpers.js +94 -0
- package/dist/archive-helpers.js.map +1 -0
- package/dist/assets/find-refs.d.ts +1 -1
- package/dist/assets/find-refs.js +1 -1
- package/dist/assets/find-refs.js.map +1 -1
- package/dist/assets/rename.js +1 -1
- package/dist/assets/rename.js.map +1 -1
- package/dist/assets/replace.js +1 -1
- package/dist/assets/replace.js.map +1 -1
- package/dist/assets/resolve.js +4 -4
- package/dist/assets/resolve.js.map +1 -1
- package/dist/assets/serve-route.js +2 -2
- package/dist/assets/serve-route.js.map +1 -1
- package/dist/assets/validate.d.ts +1 -1
- package/dist/assets/validate.js +1 -1
- package/dist/audit/config.d.ts +75 -0
- package/dist/audit/config.d.ts.map +1 -0
- package/dist/audit/config.js +91 -0
- package/dist/audit/config.js.map +1 -0
- package/dist/audit/context.d.ts +98 -0
- package/dist/audit/context.d.ts.map +1 -0
- package/dist/audit/context.js +51 -0
- package/dist/audit/context.js.map +1 -0
- package/dist/audit/errors.d.ts +73 -0
- package/dist/audit/errors.d.ts.map +1 -0
- package/dist/audit/errors.js +78 -0
- package/dist/audit/errors.js.map +1 -0
- package/dist/audit/index.d.ts +16 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +10 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/provider.d.ts +73 -0
- package/dist/audit/provider.d.ts.map +1 -0
- package/dist/audit/provider.js +2 -0
- package/dist/audit/provider.js.map +1 -0
- package/dist/audit/providers/history.d.ts +66 -0
- package/dist/audit/providers/history.d.ts.map +1 -0
- package/dist/audit/providers/history.js +102 -0
- package/dist/audit/providers/history.js.map +1 -0
- package/dist/audit/pseudonymize.d.ts +26 -0
- package/dist/audit/pseudonymize.d.ts.map +1 -0
- package/dist/audit/pseudonymize.js +86 -0
- package/dist/audit/pseudonymize.js.map +1 -0
- package/dist/audit/recorder.d.ts +102 -0
- package/dist/audit/recorder.d.ts.map +1 -0
- package/dist/audit/recorder.js +55 -0
- package/dist/audit/recorder.js.map +1 -0
- package/dist/audit/retention.d.ts +83 -0
- package/dist/audit/retention.d.ts.map +1 -0
- package/dist/audit/retention.js +142 -0
- package/dist/audit/retention.js.map +1 -0
- package/dist/audit/source-ip.d.ts +32 -0
- package/dist/audit/source-ip.d.ts.map +1 -0
- package/dist/audit/source-ip.js +164 -0
- package/dist/audit/source-ip.js.map +1 -0
- package/dist/audit/types.d.ts +143 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +33 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/audit/user-agent.d.ts +28 -0
- package/dist/audit/user-agent.d.ts.map +1 -0
- package/dist/audit/user-agent.js +63 -0
- package/dist/audit/user-agent.js.map +1 -0
- package/dist/auth/capabilities.d.ts +28 -0
- package/dist/auth/capabilities.d.ts.map +1 -0
- package/dist/auth/capabilities.js +101 -0
- package/dist/auth/capabilities.js.map +1 -0
- package/dist/auth/config.d.ts +109 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/config.js +221 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/errors.d.ts +72 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +78 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/factory.d.ts +43 -0
- package/dist/auth/factory.d.ts.map +1 -0
- package/dist/auth/factory.js +48 -0
- package/dist/auth/factory.js.map +1 -0
- package/dist/auth/index.d.ts +21 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/ip-match.d.ts +29 -0
- package/dist/auth/ip-match.d.ts.map +1 -0
- package/dist/auth/ip-match.js +162 -0
- package/dist/auth/ip-match.js.map +1 -0
- package/dist/auth/provider.d.ts +76 -0
- package/dist/auth/provider.d.ts.map +1 -0
- package/dist/auth/provider.js +2 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/providers/aws-cognito.d.ts +55 -0
- package/dist/auth/providers/aws-cognito.d.ts.map +1 -0
- package/dist/auth/providers/aws-cognito.js +114 -0
- package/dist/auth/providers/aws-cognito.js.map +1 -0
- package/dist/auth/providers/azure-easy-auth.d.ts +7 -0
- package/dist/auth/providers/azure-easy-auth.d.ts.map +1 -0
- package/dist/auth/providers/azure-easy-auth.js +48 -0
- package/dist/auth/providers/azure-easy-auth.js.map +1 -0
- package/dist/auth/providers/cloudflare-access.d.ts +71 -0
- package/dist/auth/providers/cloudflare-access.d.ts.map +1 -0
- package/dist/auth/providers/cloudflare-access.js +120 -0
- package/dist/auth/providers/cloudflare-access.js.map +1 -0
- package/dist/auth/providers/forwarded-user.d.ts +31 -0
- package/dist/auth/providers/forwarded-user.d.ts.map +1 -0
- package/dist/auth/providers/forwarded-user.js +72 -0
- package/dist/auth/providers/forwarded-user.js.map +1 -0
- package/dist/auth/providers/none.d.ts +6 -0
- package/dist/auth/providers/none.d.ts.map +1 -0
- package/dist/auth/providers/none.js +19 -0
- package/dist/auth/providers/none.js.map +1 -0
- package/dist/auth/providers/tailscale.d.ts +7 -0
- package/dist/auth/providers/tailscale.d.ts.map +1 -0
- package/dist/auth/providers/tailscale.js +30 -0
- package/dist/auth/providers/tailscale.js.map +1 -0
- package/dist/auth/role-resolver.d.ts +38 -0
- package/dist/auth/role-resolver.d.ts.map +1 -0
- package/dist/auth/role-resolver.js +92 -0
- package/dist/auth/role-resolver.js.map +1 -0
- package/dist/auth/types.d.ts +150 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +60 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cache/errors.d.ts +41 -0
- package/dist/cache/errors.d.ts.map +1 -0
- package/dist/cache/errors.js +44 -0
- package/dist/cache/errors.js.map +1 -0
- package/dist/cache/factories.d.ts +17 -0
- package/dist/cache/factories.d.ts.map +1 -0
- package/dist/cache/factories.js +17 -0
- package/dist/cache/factories.js.map +1 -0
- package/dist/cache/keys.d.ts +63 -0
- package/dist/cache/keys.d.ts.map +1 -0
- package/dist/cache/keys.js +145 -0
- package/dist/cache/keys.js.map +1 -0
- package/dist/cache/memory.d.ts +51 -0
- package/dist/cache/memory.d.ts.map +1 -0
- package/dist/cache/memory.js +204 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/per-site.d.ts +22 -0
- package/dist/cache/per-site.d.ts.map +1 -0
- package/dist/cache/per-site.js +114 -0
- package/dist/cache/per-site.js.map +1 -0
- package/dist/cache/types.d.ts +142 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +33 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/cli/archive.d.ts +44 -0
- package/dist/cli/archive.d.ts.map +1 -0
- package/dist/cli/archive.js +310 -0
- package/dist/cli/archive.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +15 -8
- package/dist/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +59 -23
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/dev-template-watcher.d.ts +29 -0
- package/dist/cli/dev-template-watcher.d.ts.map +1 -0
- package/dist/cli/dev-template-watcher.js +38 -0
- package/dist/cli/dev-template-watcher.js.map +1 -0
- package/dist/cli/history.d.ts.map +1 -1
- package/dist/cli/history.js +5 -3
- package/dist/cli/history.js.map +1 -1
- package/dist/cli/index.js +712 -395
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/validate-flags.d.ts +29 -0
- package/dist/cli/validate-flags.d.ts.map +1 -0
- package/dist/cli/validate-flags.js +49 -0
- package/dist/cli/validate-flags.js.map +1 -0
- package/dist/compare.d.ts +1 -1
- package/dist/compare.d.ts.map +1 -1
- package/dist/compare.js +25 -23
- package/dist/compare.js.map +1 -1
- package/dist/component-ids.d.ts +25 -0
- package/dist/component-ids.d.ts.map +1 -0
- package/dist/component-ids.js +83 -0
- package/dist/component-ids.js.map +1 -0
- package/dist/config/define.d.ts +61 -0
- package/dist/config/define.d.ts.map +1 -0
- package/dist/config/define.js +64 -0
- package/dist/config/define.js.map +1 -0
- package/dist/config/errors.d.ts +32 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +40 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +20 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +105 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +265 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schemas.d.ts +89 -0
- package/dist/config/schemas.d.ts.map +1 -0
- package/dist/config/schemas.js +172 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/types.d.ts +32 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +15 -0
- package/dist/config/types.js.map +1 -0
- package/dist/deploy/cloudflare-workers.d.ts +46 -0
- package/dist/deploy/cloudflare-workers.d.ts.map +1 -0
- package/dist/deploy/cloudflare-workers.js +213 -0
- package/dist/deploy/cloudflare-workers.js.map +1 -0
- package/dist/deploy/errors.d.ts +66 -0
- package/dist/deploy/errors.d.ts.map +1 -0
- package/dist/deploy/errors.js +82 -0
- package/dist/deploy/errors.js.map +1 -0
- package/dist/deploy/index.d.ts +9 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deploy/index.js +3 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/deploy/types.d.ts +162 -0
- package/dist/deploy/types.d.ts.map +1 -0
- package/dist/deploy/types.js +2 -0
- package/dist/deploy/types.js.map +1 -0
- package/dist/fragments/create.d.ts +70 -0
- package/dist/fragments/create.d.ts.map +1 -0
- package/dist/fragments/create.js +93 -0
- package/dist/fragments/create.js.map +1 -0
- package/dist/fragments/publish.d.ts +37 -0
- package/dist/fragments/publish.d.ts.map +1 -0
- package/dist/fragments/publish.js +52 -0
- package/dist/fragments/publish.js.map +1 -0
- package/dist/fragments/save.d.ts +81 -0
- package/dist/fragments/save.d.ts.map +1 -0
- package/dist/fragments/save.js +105 -0
- package/dist/fragments/save.js.map +1 -0
- package/dist/history-recorder.d.ts +5 -5
- package/dist/history-recorder.d.ts.map +1 -1
- package/dist/history-recorder.js +4 -4
- package/dist/history-recorder.js.map +1 -1
- package/dist/history-restorer.js +2 -2
- package/dist/history-restorer.js.map +1 -1
- package/dist/history.d.ts +1 -1
- package/dist/hooks/audit-emitter.d.ts +73 -0
- package/dist/hooks/audit-emitter.d.ts.map +1 -0
- package/dist/hooks/audit-emitter.js +13 -0
- package/dist/hooks/audit-emitter.js.map +1 -0
- package/dist/hooks/context.d.ts +78 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/context.js +56 -0
- package/dist/hooks/context.js.map +1 -0
- package/dist/hooks/contribution.d.ts +90 -0
- package/dist/hooks/contribution.d.ts.map +1 -0
- package/dist/hooks/contribution.js +2 -0
- package/dist/hooks/contribution.js.map +1 -0
- package/dist/hooks/dispatch.d.ts +30 -0
- package/dist/hooks/dispatch.d.ts.map +1 -0
- package/dist/hooks/dispatch.js +252 -0
- package/dist/hooks/dispatch.js.map +1 -0
- package/dist/hooks/errors.d.ts +100 -0
- package/dist/hooks/errors.d.ts.map +1 -0
- package/dist/hooks/errors.js +103 -0
- package/dist/hooks/errors.js.map +1 -0
- package/dist/hooks/index.d.ts +15 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/registry.d.ts +53 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/registry.js +139 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/storage.d.ts +43 -0
- package/dist/hooks/storage.d.ts.map +1 -0
- package/dist/hooks/storage.js +2 -0
- package/dist/hooks/storage.js.map +1 -0
- package/dist/hooks/types.d.ts +324 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +2 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +26 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -5
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +5 -1
- package/dist/locale.d.ts.map +1 -1
- package/dist/locale.js +6 -2
- package/dist/locale.js.map +1 -1
- package/dist/manifest-save.d.ts +255 -0
- package/dist/manifest-save.d.ts.map +1 -0
- package/dist/manifest-save.js +260 -0
- package/dist/manifest-save.js.map +1 -0
- package/dist/manifest.d.ts +1 -2
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +43 -44
- package/dist/manifest.js.map +1 -1
- package/dist/node-floor.d.ts +3 -0
- package/dist/node-floor.d.ts.map +1 -0
- package/dist/node-floor.js +3 -0
- package/dist/node-floor.js.map +1 -0
- package/dist/pages/create.d.ts +103 -0
- package/dist/pages/create.d.ts.map +1 -0
- package/dist/pages/create.js +117 -0
- package/dist/pages/create.js.map +1 -0
- package/dist/pages/publish.d.ts +59 -0
- package/dist/pages/publish.d.ts.map +1 -0
- package/dist/pages/publish.js +78 -0
- package/dist/pages/publish.js.map +1 -0
- package/dist/pages/save.d.ts +97 -0
- package/dist/pages/save.d.ts.map +1 -0
- package/dist/pages/save.js +138 -0
- package/dist/pages/save.js.map +1 -0
- package/dist/providers/factories.d.ts +65 -0
- package/dist/providers/factories.d.ts.map +1 -0
- package/dist/providers/factories.js +189 -0
- package/dist/providers/factories.js.map +1 -0
- package/dist/publish-item.d.ts +225 -0
- package/dist/publish-item.d.ts.map +1 -0
- package/dist/publish-item.js +210 -0
- package/dist/publish-item.js.map +1 -0
- package/dist/publish-rendered.d.ts.map +1 -1
- package/dist/publish-rendered.js +75 -6
- package/dist/publish-rendered.js.map +1 -1
- package/dist/publish-renderers.d.ts +132 -0
- package/dist/publish-renderers.d.ts.map +1 -0
- package/dist/publish-renderers.js +240 -0
- package/dist/publish-renderers.js.map +1 -0
- package/dist/publish-run.d.ts +223 -0
- package/dist/publish-run.d.ts.map +1 -0
- package/dist/publish-run.js +307 -0
- package/dist/publish-run.js.map +1 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +1 -10
- package/dist/publish.js.map +1 -1
- package/dist/render-for-analysis.d.ts +24 -0
- package/dist/render-for-analysis.d.ts.map +1 -0
- package/dist/render-for-analysis.js +146 -0
- package/dist/render-for-analysis.js.map +1 -0
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +47 -23
- package/dist/resolver.js.map +1 -1
- package/dist/runtime/archive-marker.d.ts +62 -0
- package/dist/runtime/archive-marker.d.ts.map +1 -0
- package/dist/runtime/archive-marker.js +88 -0
- package/dist/runtime/archive-marker.js.map +1 -0
- package/dist/runtime/capability-gap-warnings.d.ts +42 -0
- package/dist/runtime/capability-gap-warnings.d.ts.map +1 -0
- package/dist/runtime/capability-gap-warnings.js +28 -0
- package/dist/runtime/capability-gap-warnings.js.map +1 -0
- package/dist/runtime/redirects-emit.d.ts +93 -0
- package/dist/runtime/redirects-emit.d.ts.map +1 -0
- package/dist/runtime/redirects-emit.js +89 -0
- package/dist/runtime/redirects-emit.js.map +1 -0
- package/dist/runtime/runtime-capabilities.d.ts +79 -0
- package/dist/runtime/runtime-capabilities.d.ts.map +1 -0
- package/dist/runtime/runtime-capabilities.js +60 -0
- package/dist/runtime/runtime-capabilities.js.map +1 -0
- package/dist/save-etag.d.ts +69 -0
- package/dist/save-etag.d.ts.map +1 -0
- package/dist/save-etag.js +118 -0
- package/dist/save-etag.js.map +1 -0
- package/dist/site-loader.d.ts +42 -4
- package/dist/site-loader.d.ts.map +1 -1
- package/dist/site-loader.js +27 -8
- package/dist/site-loader.js.map +1 -1
- package/dist/targets.d.ts +21 -12
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +27 -95
- package/dist/targets.js.map +1 -1
- package/dist/testing/admin-cache-contract.d.ts +52 -0
- package/dist/testing/admin-cache-contract.d.ts.map +1 -0
- package/dist/testing/admin-cache-contract.js +203 -0
- package/dist/testing/admin-cache-contract.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +11 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/transforms/factories.d.ts +16 -0
- package/dist/transforms/factories.d.ts.map +1 -0
- package/dist/transforms/factories.js +18 -0
- package/dist/transforms/factories.js.map +1 -0
- package/dist/transforms/index.d.ts +10 -17
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/index.js +4 -28
- package/dist/transforms/index.js.map +1 -1
- package/dist/transforms/sharp.d.ts +15 -1
- package/dist/transforms/sharp.d.ts.map +1 -1
- package/dist/transforms/sharp.js +34 -20
- package/dist/transforms/sharp.js.map +1 -1
- package/dist/types.d.ts +379 -52
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +20 -1
- package/dist/types.js.map +1 -1
- package/dist/validation/alt-required-walker.d.ts +27 -0
- package/dist/validation/alt-required-walker.d.ts.map +1 -0
- package/dist/validation/alt-required-walker.js +108 -0
- package/dist/validation/alt-required-walker.js.map +1 -0
- package/dist/validation/default-registry.d.ts +12 -0
- package/dist/validation/default-registry.d.ts.map +1 -0
- package/dist/validation/default-registry.js +55 -0
- package/dist/validation/default-registry.js.map +1 -0
- package/dist/validation/publish-audit.d.ts +44 -0
- package/dist/validation/publish-audit.d.ts.map +1 -0
- package/dist/validation/publish-audit.js +64 -0
- package/dist/validation/publish-audit.js.map +1 -0
- package/dist/validation/registry.d.ts +23 -0
- package/dist/validation/registry.d.ts.map +1 -0
- package/dist/validation/registry.js +15 -0
- package/dist/validation/registry.js.map +1 -0
- package/dist/validation/save-delta.d.ts +46 -0
- package/dist/validation/save-delta.d.ts.map +1 -0
- package/dist/validation/save-delta.js +57 -0
- package/dist/validation/save-delta.js.map +1 -0
- package/dist/validation/scanner.d.ts +91 -0
- package/dist/validation/scanner.d.ts.map +1 -0
- package/dist/validation/scanner.js +327 -0
- package/dist/validation/scanner.js.map +1 -0
- package/dist/validation/template-impact.d.ts +52 -0
- package/dist/validation/template-impact.d.ts.map +1 -0
- package/dist/validation/template-impact.js +53 -0
- package/dist/validation/template-impact.js.map +1 -0
- package/dist/validation/types.d.ts +123 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +7 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation/validators/accessibility.d.ts +3 -0
- package/dist/validation/validators/accessibility.d.ts.map +1 -0
- package/dist/validation/validators/accessibility.js +106 -0
- package/dist/validation/validators/accessibility.js.map +1 -0
- package/dist/validation/validators/aliasof-points-to-archived.d.ts +40 -0
- package/dist/validation/validators/aliasof-points-to-archived.d.ts.map +1 -0
- package/dist/validation/validators/aliasof-points-to-archived.js +34 -0
- package/dist/validation/validators/aliasof-points-to-archived.js.map +1 -0
- package/dist/validation/validators/alt-required.d.ts +3 -0
- package/dist/validation/validators/alt-required.d.ts.map +1 -0
- package/dist/validation/validators/alt-required.js +118 -0
- package/dist/validation/validators/alt-required.js.map +1 -0
- package/dist/validation/validators/archive-not-supported-on-target.d.ts +3 -0
- package/dist/validation/validators/archive-not-supported-on-target.d.ts.map +1 -0
- package/dist/validation/validators/archive-not-supported-on-target.js +38 -0
- package/dist/validation/validators/archive-not-supported-on-target.js.map +1 -0
- package/dist/validation/validators/broken-links.d.ts +3 -0
- package/dist/validation/validators/broken-links.d.ts.map +1 -0
- package/dist/validation/validators/broken-links.js +190 -0
- package/dist/validation/validators/broken-links.js.map +1 -0
- package/dist/validation/validators/circular-alias.d.ts +36 -0
- package/dist/validation/validators/circular-alias.d.ts.map +1 -0
- package/dist/validation/validators/circular-alias.js +63 -0
- package/dist/validation/validators/circular-alias.js.map +1 -0
- package/dist/validation/validators/circular-fragment.d.ts +15 -0
- package/dist/validation/validators/circular-fragment.d.ts.map +1 -0
- package/dist/validation/validators/circular-fragment.js +97 -0
- package/dist/validation/validators/circular-fragment.js.map +1 -0
- package/dist/validation/validators/dangling-alias.d.ts +38 -0
- package/dist/validation/validators/dangling-alias.d.ts.map +1 -0
- package/dist/validation/validators/dangling-alias.js +31 -0
- package/dist/validation/validators/dangling-alias.js.map +1 -0
- package/dist/validation/validators/deploy-target-type-supported.d.ts +3 -0
- package/dist/validation/validators/deploy-target-type-supported.d.ts.map +1 -0
- package/dist/validation/validators/deploy-target-type-supported.js +32 -0
- package/dist/validation/validators/deploy-target-type-supported.js.map +1 -0
- package/dist/validation/validators/dynamic-route-conflict.d.ts +18 -0
- package/dist/validation/validators/dynamic-route-conflict.d.ts.map +1 -0
- package/dist/validation/validators/dynamic-route-conflict.js +80 -0
- package/dist/validation/validators/dynamic-route-conflict.js.map +1 -0
- package/dist/validation/validators/html-validity.d.ts +3 -0
- package/dist/validation/validators/html-validity.d.ts.map +1 -0
- package/dist/validation/validators/html-validity.js +89 -0
- package/dist/validation/validators/html-validity.js.map +1 -0
- package/dist/validation/validators/orphaned-locale-file.d.ts +21 -0
- package/dist/validation/validators/orphaned-locale-file.d.ts.map +1 -0
- package/dist/validation/validators/orphaned-locale-file.js +84 -0
- package/dist/validation/validators/orphaned-locale-file.js.map +1 -0
- package/dist/validation/validators/referenced-archived-without-alias.d.ts +3 -0
- package/dist/validation/validators/referenced-archived-without-alias.d.ts.map +1 -0
- package/dist/validation/validators/referenced-archived-without-alias.js +65 -0
- package/dist/validation/validators/referenced-archived-without-alias.js.map +1 -0
- package/dist/validation/validators/referenced-asset-exists.d.ts +13 -0
- package/dist/validation/validators/referenced-asset-exists.d.ts.map +1 -0
- package/dist/validation/validators/referenced-asset-exists.js +80 -0
- package/dist/validation/validators/referenced-asset-exists.js.map +1 -0
- package/dist/validation/validators/referenced-fragment-exists.d.ts +9 -0
- package/dist/validation/validators/referenced-fragment-exists.d.ts.map +1 -0
- package/dist/validation/validators/referenced-fragment-exists.js +52 -0
- package/dist/validation/validators/referenced-fragment-exists.js.map +1 -0
- package/dist/validation/validators/referenced-template-exists.d.ts +10 -0
- package/dist/validation/validators/referenced-template-exists.d.ts.map +1 -0
- package/dist/validation/validators/referenced-template-exists.js +74 -0
- package/dist/validation/validators/referenced-template-exists.js.map +1 -0
- package/dist/validation/validators/schema-conformance.d.ts +17 -0
- package/dist/validation/validators/schema-conformance.d.ts.map +1 -0
- package/dist/validation/validators/schema-conformance.js +94 -0
- package/dist/validation/validators/schema-conformance.js.map +1 -0
- package/dist/validation/validators/target-deploy-coverage.d.ts +3 -0
- package/dist/validation/validators/target-deploy-coverage.d.ts.map +1 -0
- package/dist/validation/validators/target-deploy-coverage.js +37 -0
- package/dist/validation/validators/target-deploy-coverage.js.map +1 -0
- package/dist/validation/validators/unused-fragment.d.ts +16 -0
- package/dist/validation/validators/unused-fragment.d.ts.map +1 -0
- package/dist/validation/validators/unused-fragment.js +86 -0
- package/dist/validation/validators/unused-fragment.js.map +1 -0
- package/package.json +54 -31
- package/admin-dist/assets/index-BO9-CXmW.css +0 -1
- package/admin-dist/assets/index-Ufu8zZH_.js +0 -668
- package/admin-dist/assets/rolldown-runtime-COnpUsM8.js +0 -1
- package/admin-dist/assets/vendor-rjsf-HKBAjOmQ.js +0 -32
- package/admin-dist/assets/vendor-tiptap-IyO99U4R.js +0 -142
- package/admin-dist/assets/vendor-vue-D3wBSmDf.js +0 -1
- package/dist/publish-locale.d.ts +0 -44
- package/dist/publish-locale.d.ts.map +0 -1
- package/dist/publish-locale.js +0 -103
- package/dist/publish-locale.js.map +0 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background validation scanner — runs all background-stage validators across
|
|
3
|
+
* the site and exposes the resulting issues to the admin API + admin UI.
|
|
4
|
+
*
|
|
5
|
+
* Per design-validation.md "Background scanner (Cut 2)" + the implementation
|
|
6
|
+
* plan in design-validation-implementation.md:
|
|
7
|
+
*
|
|
8
|
+
* - Initial full-site scan on admin boot.
|
|
9
|
+
* - Incremental rescan after save: affected item + transitive dependents
|
|
10
|
+
* (fragment edits invalidate pages via `findDependentsFromSidecars`; asset
|
|
11
|
+
* edits invalidate referencing items via `readRefsForAsset`; template edits
|
|
12
|
+
* trigger a full-site rescan since no `template-deps` reverse-dep relation
|
|
13
|
+
* exists yet).
|
|
14
|
+
* - Per-item validation cache keyed by content hash (via `AdminCache`).
|
|
15
|
+
* Same content = same issues; cache hit short-circuits the validators.
|
|
16
|
+
* - Result store keyed by item path; reads return current issues.
|
|
17
|
+
* - SSE subscribers fired when a scan pass completes (admin UI dot updates).
|
|
18
|
+
*
|
|
19
|
+
* # Multi-instance discipline
|
|
20
|
+
*
|
|
21
|
+
* The scanner is per-instance scope. Each admin instance maintains its own
|
|
22
|
+
* result store + cache; SSE invalidation isn't broadcast across instances.
|
|
23
|
+
* Acceptable because: (a) each instance scans independently from the same
|
|
24
|
+
* source-of-truth storage; (b) save-side invalidation is per-instance via
|
|
25
|
+
* the same code path that wrote the manifest; (c) external changes (git
|
|
26
|
+
* pull) flow through `gazetta dev`'s file watcher per-instance.
|
|
27
|
+
*
|
|
28
|
+
* # SOLID lenses
|
|
29
|
+
*
|
|
30
|
+
* - SRP: scanner orchestrates passes. It doesn't implement validators
|
|
31
|
+
* (that's per-validator) and doesn't render UI (that's the admin UI).
|
|
32
|
+
* - DIP: depends on `AdminCache` interface, not `MemoryCache`; depends on
|
|
33
|
+
* the validator registry contract, not specific validators.
|
|
34
|
+
* - OCP: adding a new background-stage validator means registering it in
|
|
35
|
+
* `defaultValidatorRegistry()`; the scanner picks it up automatically
|
|
36
|
+
* via `registry.forStage('background')`.
|
|
37
|
+
*/
|
|
38
|
+
import { createHash } from 'node:crypto';
|
|
39
|
+
import { findDependentsFromSidecars } from '../publish.js';
|
|
40
|
+
import { renderPageForAnalysis } from '../render-for-analysis.js';
|
|
41
|
+
import { allFragmentEntries, allPageEntries, loadSite } from '../site-loader.js';
|
|
42
|
+
/**
|
|
43
|
+
* Construct a scanner. The scanner doesn't kick off `scanAll()` automatically;
|
|
44
|
+
* callers (CLI boot path) call it after constructing.
|
|
45
|
+
*/
|
|
46
|
+
export function createValidationScanner(opts) {
|
|
47
|
+
const { storage, contentRoot, registry, cache, siteOptions } = opts;
|
|
48
|
+
const loadSiteFn = opts.loadSiteImpl ?? loadSite;
|
|
49
|
+
const issuesByItem = new Map();
|
|
50
|
+
const subscribers = new Set();
|
|
51
|
+
function setIssues(itemPath, issues) {
|
|
52
|
+
if (issues.length === 0)
|
|
53
|
+
issuesByItem.delete(itemPath);
|
|
54
|
+
else
|
|
55
|
+
issuesByItem.set(itemPath, [...issues]);
|
|
56
|
+
}
|
|
57
|
+
function totalIssues() {
|
|
58
|
+
let n = 0;
|
|
59
|
+
for (const arr of issuesByItem.values())
|
|
60
|
+
n += arr.length;
|
|
61
|
+
return n;
|
|
62
|
+
}
|
|
63
|
+
function emit(event) {
|
|
64
|
+
for (const sub of subscribers) {
|
|
65
|
+
try {
|
|
66
|
+
sub(event);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Subscriber faults isolated; one bad subscriber doesn't block siblings.
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function loadFreshSite() {
|
|
74
|
+
return loadSiteFn({ contentRoot, ...siteOptions });
|
|
75
|
+
}
|
|
76
|
+
async function validateItem(site, item, manifest) {
|
|
77
|
+
const hash = hashManifestStable(manifest);
|
|
78
|
+
const key = cacheKey(item, hash);
|
|
79
|
+
const cached = await cache.get(key);
|
|
80
|
+
if (cached !== null) {
|
|
81
|
+
// Re-stamp the store from cache (cheap; covers boot warm-up too).
|
|
82
|
+
setIssues(item.itemPath, cached);
|
|
83
|
+
return cached;
|
|
84
|
+
}
|
|
85
|
+
const validators = registry.forStage('background');
|
|
86
|
+
const renderedOutput = makeRenderedOutputAccess(site);
|
|
87
|
+
const issues = [];
|
|
88
|
+
for (const v of validators) {
|
|
89
|
+
try {
|
|
90
|
+
const out = await v.validate({
|
|
91
|
+
stage: 'background',
|
|
92
|
+
site,
|
|
93
|
+
contentRoot,
|
|
94
|
+
storage,
|
|
95
|
+
scope: { kind: 'background', item, manifest },
|
|
96
|
+
renderedOutput,
|
|
97
|
+
});
|
|
98
|
+
issues.push(...out);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
// Validator threw — surface as an info issue so the scan finishes.
|
|
102
|
+
issues.push({
|
|
103
|
+
validator: v.name,
|
|
104
|
+
severity: 'info',
|
|
105
|
+
message: `Validator "${v.name}" failed: ${err.message}`,
|
|
106
|
+
itemPath: item.itemPath,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
await cache.set(key, issues);
|
|
111
|
+
setIssues(item.itemPath, issues);
|
|
112
|
+
return issues;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build a `RenderedOutputAccess` adapter for this scan pass. Validators
|
|
116
|
+
* that need rendered HTML (a11y, html-validity) opt in via the
|
|
117
|
+
* `renderedOutput` field of their input. Validators that don't need it
|
|
118
|
+
* (the 5 ref-existence validators, schema-conformance, altRequired) can
|
|
119
|
+
* ignore the field — they don't trigger a render.
|
|
120
|
+
*
|
|
121
|
+
* The render is itself cached via render-for-analysis's own AdminCache
|
|
122
|
+
* key (content + template + dependency hash), separate from the scanner's
|
|
123
|
+
* issues cache. Same content = same HTML across scans.
|
|
124
|
+
*
|
|
125
|
+
* Fragments aren't rendered as full pages; `htmlFor` returns null for
|
|
126
|
+
* fragment items. Validators that consume rendered output guard on null.
|
|
127
|
+
*/
|
|
128
|
+
function makeRenderedOutputAccess(site) {
|
|
129
|
+
return {
|
|
130
|
+
async htmlFor(item) {
|
|
131
|
+
if (item.kind !== 'page')
|
|
132
|
+
return null;
|
|
133
|
+
if (!siteOptions.templatesDir)
|
|
134
|
+
return null;
|
|
135
|
+
const out = await renderPageForAnalysis(item.name, {
|
|
136
|
+
site,
|
|
137
|
+
cache,
|
|
138
|
+
templatesDir: siteOptions.templatesDir,
|
|
139
|
+
});
|
|
140
|
+
return out?.html ?? null;
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Shared full-site walk — extracted so scanAll(), rescan({template}),
|
|
145
|
+
// and rescan({full}) share the body. Returns the loaded `site` +
|
|
146
|
+
// wall-clock + count so the caller can decide what the ScanEvent
|
|
147
|
+
// carries (e.g., template rescan adds affectedItemCount to the cause
|
|
148
|
+
// before emitting).
|
|
149
|
+
async function fullScanWalk() {
|
|
150
|
+
const start = Date.now();
|
|
151
|
+
const site = await loadFreshSite();
|
|
152
|
+
let scanned = 0;
|
|
153
|
+
const seen = new Set();
|
|
154
|
+
for (const entry of allPageEntries(site)) {
|
|
155
|
+
const item = {
|
|
156
|
+
kind: 'page',
|
|
157
|
+
name: entry.name,
|
|
158
|
+
itemPath: itemPathFor('page', entry.page.dir, entry.locale),
|
|
159
|
+
};
|
|
160
|
+
if (seen.has(item.itemPath))
|
|
161
|
+
continue;
|
|
162
|
+
seen.add(item.itemPath);
|
|
163
|
+
await validateItem(site, item, entry.page);
|
|
164
|
+
scanned++;
|
|
165
|
+
}
|
|
166
|
+
for (const entry of allFragmentEntries(site)) {
|
|
167
|
+
const item = {
|
|
168
|
+
kind: 'fragment',
|
|
169
|
+
name: entry.name,
|
|
170
|
+
itemPath: itemPathFor('fragment', entry.fragment.dir, entry.locale),
|
|
171
|
+
};
|
|
172
|
+
if (seen.has(item.itemPath))
|
|
173
|
+
continue;
|
|
174
|
+
seen.add(item.itemPath);
|
|
175
|
+
await validateItem(site, item, entry.fragment);
|
|
176
|
+
scanned++;
|
|
177
|
+
}
|
|
178
|
+
// Stale items in the store (deleted since last scan) get pruned.
|
|
179
|
+
for (const path of [...issuesByItem.keys()]) {
|
|
180
|
+
if (!seen.has(path))
|
|
181
|
+
issuesByItem.delete(path);
|
|
182
|
+
}
|
|
183
|
+
return { site, durationMs: Date.now() - start, scanned };
|
|
184
|
+
}
|
|
185
|
+
async function scanAll() {
|
|
186
|
+
const { durationMs, scanned } = await fullScanWalk();
|
|
187
|
+
emit({ durationMs, scanned, totalIssues: totalIssues() });
|
|
188
|
+
}
|
|
189
|
+
async function rescan(cause) {
|
|
190
|
+
if (cause.kind === 'template') {
|
|
191
|
+
// Template rescan = full-site walk. Compute affectedItemCount
|
|
192
|
+
// post-walk so the emitted ScanEvent (and downstream SSE
|
|
193
|
+
// template-changed event) carries the banner's "N items
|
|
194
|
+
// affected" number in one go — no double emit, no client-side
|
|
195
|
+
// re-walk. Affected = items using the template that have any
|
|
196
|
+
// issue post-scan; issuesByItem is up to date by this point.
|
|
197
|
+
const { site, durationMs, scanned } = await fullScanWalk();
|
|
198
|
+
let affectedItemCount;
|
|
199
|
+
try {
|
|
200
|
+
const { computeTemplateImpact } = await import('./template-impact.js');
|
|
201
|
+
affectedItemCount = computeTemplateImpact(site, cause.name, path => issuesByItem.get(path) ?? []).affectedItemCount;
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
// Best-effort — banner just shows the template name without a
|
|
205
|
+
// count when this fails. The walk's per-item issues already
|
|
206
|
+
// surfaced via the regular store, which feeds dots + drawer.
|
|
207
|
+
console.warn(` Validation scanner: template-impact count failed for "${cause.name}": ${err.message}`);
|
|
208
|
+
}
|
|
209
|
+
emit({
|
|
210
|
+
durationMs,
|
|
211
|
+
scanned,
|
|
212
|
+
totalIssues: totalIssues(),
|
|
213
|
+
cause: { ...cause, affectedItemCount },
|
|
214
|
+
});
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (cause.kind === 'full') {
|
|
218
|
+
const { durationMs, scanned } = await fullScanWalk();
|
|
219
|
+
emit({ durationMs, scanned, totalIssues: totalIssues(), cause });
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const start = Date.now();
|
|
223
|
+
const site = await loadFreshSite();
|
|
224
|
+
let scanned = 0;
|
|
225
|
+
const targets = await targetsForCause(cause, site, contentRoot);
|
|
226
|
+
for (const target of targets) {
|
|
227
|
+
const manifest = manifestForItem(site, target);
|
|
228
|
+
if (!manifest)
|
|
229
|
+
continue; // item disappeared between save and rescan
|
|
230
|
+
await validateItem(site, target, manifest);
|
|
231
|
+
scanned++;
|
|
232
|
+
}
|
|
233
|
+
emit({ durationMs: Date.now() - start, scanned, totalIssues: totalIssues(), cause });
|
|
234
|
+
}
|
|
235
|
+
function allIssues() {
|
|
236
|
+
const out = [];
|
|
237
|
+
for (const arr of issuesByItem.values())
|
|
238
|
+
out.push(...arr);
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
function issuesFor(itemPath) {
|
|
242
|
+
return issuesByItem.get(itemPath) ?? [];
|
|
243
|
+
}
|
|
244
|
+
function subscribe(handler) {
|
|
245
|
+
subscribers.add(handler);
|
|
246
|
+
return () => subscribers.delete(handler);
|
|
247
|
+
}
|
|
248
|
+
return { scanAll, rescan, allIssues, issuesFor, subscribe };
|
|
249
|
+
}
|
|
250
|
+
// ---- helpers --------------------------------------------------------------
|
|
251
|
+
function itemPathFor(kind, dir, locale) {
|
|
252
|
+
const base = kind === 'page' ? 'page' : 'fragment';
|
|
253
|
+
const ext = locale ? `${base}.${locale}.json` : `${base}.json`;
|
|
254
|
+
return `${dir}/${ext}`;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Stable hash of a manifest for cache keying. Crypto-grade — same content =
|
|
258
|
+
* same hash across processes. Different from the publish-time
|
|
259
|
+
* `hashManifest()` (which folds in template + fragment hashes); the scanner
|
|
260
|
+
* cares only about manifest content for invalidation purposes.
|
|
261
|
+
*
|
|
262
|
+
* Canonicalizes nested objects by recursively sorting keys before
|
|
263
|
+
* serializing. JSON.stringify's replacer-array form only filters top-level
|
|
264
|
+
* keys, which would silently miss nested mutations.
|
|
265
|
+
*/
|
|
266
|
+
function hashManifestStable(manifest) {
|
|
267
|
+
return createHash('sha256').update(canonicalJson(manifest)).digest('hex').slice(0, 16);
|
|
268
|
+
}
|
|
269
|
+
function canonicalJson(value) {
|
|
270
|
+
if (value === null || typeof value !== 'object')
|
|
271
|
+
return JSON.stringify(value);
|
|
272
|
+
if (Array.isArray(value))
|
|
273
|
+
return `[${value.map(canonicalJson).join(',')}]`;
|
|
274
|
+
const obj = value;
|
|
275
|
+
const keys = Object.keys(obj).sort();
|
|
276
|
+
const parts = keys.map(k => `${JSON.stringify(k)}:${canonicalJson(obj[k])}`);
|
|
277
|
+
return `{${parts.join(',')}}`;
|
|
278
|
+
}
|
|
279
|
+
function cacheKey(item, contentHash) {
|
|
280
|
+
return `validation:${item.kind}:${encodePath(item.itemPath)}:${contentHash}`;
|
|
281
|
+
}
|
|
282
|
+
function encodePath(path) {
|
|
283
|
+
return path.replace(/[/]/g, '.').replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
284
|
+
}
|
|
285
|
+
async function targetsForCause(cause, site, contentRoot) {
|
|
286
|
+
if (cause.kind === 'manifest')
|
|
287
|
+
return [cause.item];
|
|
288
|
+
if (cause.kind === 'fragment') {
|
|
289
|
+
// Affected: the fragment itself + every page/fragment that references it.
|
|
290
|
+
const out = [];
|
|
291
|
+
const frag = site.fragments.get(cause.name);
|
|
292
|
+
if (frag) {
|
|
293
|
+
out.push({ kind: 'fragment', name: cause.name, itemPath: `${frag.dir}/fragment.json` });
|
|
294
|
+
}
|
|
295
|
+
const dependents = await findDependentsFromSidecars(contentRoot, { fragment: cause.name });
|
|
296
|
+
for (const pageName of dependents.pages) {
|
|
297
|
+
const page = site.pages.get(pageName);
|
|
298
|
+
if (page)
|
|
299
|
+
out.push({ kind: 'page', name: pageName, itemPath: `${page.dir}/page.json` });
|
|
300
|
+
}
|
|
301
|
+
for (const fragName of dependents.fragments) {
|
|
302
|
+
const f = site.fragments.get(fragName);
|
|
303
|
+
if (f)
|
|
304
|
+
out.push({ kind: 'fragment', name: fragName, itemPath: `${f.dir}/fragment.json` });
|
|
305
|
+
}
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
308
|
+
if (cause.kind === 'asset') {
|
|
309
|
+
// readRefsForAsset would re-introduce a coupling we don't want here;
|
|
310
|
+
// for v1, treat asset edits as full-site rescan. The cost is low at
|
|
311
|
+
// envelope (5K pages x ~10ms validate per item = 50s worst case;
|
|
312
|
+
// typical scans are <1s thanks to cache hits).
|
|
313
|
+
const out = [];
|
|
314
|
+
for (const entry of allPageEntries(site)) {
|
|
315
|
+
out.push({ kind: 'page', name: entry.name, itemPath: itemPathFor('page', entry.page.dir, entry.locale) });
|
|
316
|
+
}
|
|
317
|
+
return out;
|
|
318
|
+
}
|
|
319
|
+
// Unreachable per type guards above.
|
|
320
|
+
return [];
|
|
321
|
+
}
|
|
322
|
+
function manifestForItem(site, item) {
|
|
323
|
+
if (item.kind === 'page')
|
|
324
|
+
return site.pages.get(item.name) ?? null;
|
|
325
|
+
return site.fragments.get(item.name) ?? null;
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/validation/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template impact analysis (Validation Cut 6).
|
|
3
|
+
*
|
|
4
|
+
* Walks the loaded site to find every page + fragment that uses a given
|
|
5
|
+
* template — top-level (manifest.template === templateName) AND nested
|
|
6
|
+
* inline components (recursively). Pairs with the scanner store's
|
|
7
|
+
* `issuesFor(itemPath)` to project the per-template impact view that
|
|
8
|
+
* the DevPlayground "Impact" tab + the toolbar banner consume.
|
|
9
|
+
*
|
|
10
|
+
* Surface shape matches what `GET /api/templates/:name/impact` returns:
|
|
11
|
+
* a flat list of items, ordered pages-first then fragments, with
|
|
12
|
+
* deduplication so a page that uses the template multiple times shows
|
|
13
|
+
* once (its issues already aggregate at the item level).
|
|
14
|
+
*
|
|
15
|
+
* # SOLID lenses
|
|
16
|
+
*
|
|
17
|
+
* - SRP: this module owns the template→items walk. Issue lookup
|
|
18
|
+
* stays at the scanner; rendering stays at the route.
|
|
19
|
+
* - DIP: takes the loaded `Site` + a thin issue-lookup function.
|
|
20
|
+
* No coupling to the scanner's internal store.
|
|
21
|
+
* - OCP: adding a new component-nesting shape (e.g., grid columns
|
|
22
|
+
* carrying templates) extends the recursive walk without
|
|
23
|
+
* touching the lookup function.
|
|
24
|
+
*/
|
|
25
|
+
import type { Site } from '../site-loader.js';
|
|
26
|
+
import type { Issue } from './types.js';
|
|
27
|
+
export interface TemplateImpactItem {
|
|
28
|
+
/** Page or fragment. */
|
|
29
|
+
kind: 'page' | 'fragment';
|
|
30
|
+
/** Item name (e.g., 'home' or 'header'). */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Manifest path matching the scanner's itemPath shape. */
|
|
33
|
+
itemPath: string;
|
|
34
|
+
/** Issues from the scanner store for this item. May be empty (clean). */
|
|
35
|
+
issues: readonly Issue[];
|
|
36
|
+
}
|
|
37
|
+
export interface TemplateImpactResult {
|
|
38
|
+
/** The template the impact view describes. */
|
|
39
|
+
template: string;
|
|
40
|
+
/** Items using the template, pages first then fragments. */
|
|
41
|
+
items: readonly TemplateImpactItem[];
|
|
42
|
+
/** Convenience: items.filter(i => i.issues.length > 0).length. */
|
|
43
|
+
affectedItemCount: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Compute the impact view for `templateName` against `site`.
|
|
47
|
+
*
|
|
48
|
+
* `issuesFor(itemPath)` is the scanner's per-item issue lookup —
|
|
49
|
+
* passed in so this module stays decoupled from the scanner.
|
|
50
|
+
*/
|
|
51
|
+
export declare function computeTemplateImpact(site: Site, templateName: string, issuesFor: (itemPath: string) => readonly Issue[]): TemplateImpactResult;
|
|
52
|
+
//# sourceMappingURL=template-impact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-impact.d.ts","sourceRoot":"","sources":["../../src/validation/template-impact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAG7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IACzB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACpC,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,KAAK,EAAE,GAChD,oBAAoB,CAqBtB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { manifestComponents } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Compute the impact view for `templateName` against `site`.
|
|
4
|
+
*
|
|
5
|
+
* `issuesFor(itemPath)` is the scanner's per-item issue lookup —
|
|
6
|
+
* passed in so this module stays decoupled from the scanner.
|
|
7
|
+
*/
|
|
8
|
+
export function computeTemplateImpact(site, templateName, issuesFor) {
|
|
9
|
+
const items = [];
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
for (const [name, page] of site.pages) {
|
|
12
|
+
if (!usesTemplate(page, templateName))
|
|
13
|
+
continue;
|
|
14
|
+
const itemPath = `${page.dir}/page.json`;
|
|
15
|
+
if (seen.has(itemPath))
|
|
16
|
+
continue;
|
|
17
|
+
seen.add(itemPath);
|
|
18
|
+
items.push({ kind: 'page', name, itemPath, issues: issuesFor(itemPath) });
|
|
19
|
+
}
|
|
20
|
+
for (const [name, fragment] of site.fragments) {
|
|
21
|
+
if (!usesTemplate(fragment, templateName))
|
|
22
|
+
continue;
|
|
23
|
+
const itemPath = `${fragment.dir}/fragment.json`;
|
|
24
|
+
if (seen.has(itemPath))
|
|
25
|
+
continue;
|
|
26
|
+
seen.add(itemPath);
|
|
27
|
+
items.push({ kind: 'fragment', name, itemPath, issues: issuesFor(itemPath) });
|
|
28
|
+
}
|
|
29
|
+
const affectedItemCount = items.reduce((n, item) => (item.issues.length > 0 ? n + 1 : n), 0);
|
|
30
|
+
return { template: templateName, items, affectedItemCount };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Does this manifest (or any of its nested inline components) reference
|
|
34
|
+
* `templateName`? Top-level template + recursive component walk.
|
|
35
|
+
*/
|
|
36
|
+
function usesTemplate(manifest, templateName) {
|
|
37
|
+
if (manifest.template === templateName)
|
|
38
|
+
return true;
|
|
39
|
+
return entriesReferenceTemplate(manifestComponents(manifest), templateName);
|
|
40
|
+
}
|
|
41
|
+
function entriesReferenceTemplate(entries, templateName) {
|
|
42
|
+
for (const entry of entries) {
|
|
43
|
+
if (typeof entry === 'string')
|
|
44
|
+
continue; // fragment ref — not a template ref
|
|
45
|
+
const inline = entry;
|
|
46
|
+
if (inline.template === templateName)
|
|
47
|
+
return true;
|
|
48
|
+
if (inline.components && entriesReferenceTemplate(inline.components, templateName))
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=template-impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-impact.js","sourceRoot":"","sources":["../../src/validation/template-impact.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAuB/C;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAU,EACV,YAAoB,EACpB,SAAiD;IAEjD,MAAM,KAAK,GAAyB,EAAE,CAAA;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAE9B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC;YAAE,SAAQ;QAC/C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,YAAY,CAAA;QACxC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAQ;QAChC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC3E,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9C,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,YAAY,CAAC;YAAE,SAAQ;QACnD,MAAM,QAAQ,GAAG,GAAG,QAAQ,CAAC,GAAG,gBAAgB,CAAA;QAChD,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAQ;QAChC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5F,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAA;AAC7D,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,QAAyC,EAAE,YAAoB;IACnF,IAAI,QAAQ,CAAC,QAAQ,KAAK,YAAY;QAAE,OAAO,IAAI,CAAA;IACnD,OAAO,wBAAwB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,wBAAwB,CAAC,OAAkC,EAAE,YAAoB;IACxF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAQ,CAAC,oCAAoC;QAC5E,MAAM,MAAM,GAAG,KAAwB,CAAA;QACvC,IAAI,MAAM,CAAC,QAAQ,KAAK,YAAY;YAAE,OAAO,IAAI,CAAA;QACjD,IAAI,MAAM,CAAC,UAAU,IAAI,wBAAwB,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC;YAAE,OAAO,IAAI,CAAA;IACjG,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { ComponentEntry, PageManifest, FragmentManifest, StorageProvider } from '../types.js';
|
|
2
|
+
import type { Site } from '../site-loader.js';
|
|
3
|
+
import type { ContentRoot } from '../content-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* Lifecycle stages a validator can run at. Per design-validation.md,
|
|
6
|
+
* these correspond to the four-phase model.
|
|
7
|
+
*/
|
|
8
|
+
export type ValidationStage = 'save-delta' | 'background' | 'pre-publish' | 'cli';
|
|
9
|
+
/**
|
|
10
|
+
* Severity of a single issue. Per stage, validators declare a default;
|
|
11
|
+
* operators can promote/demote at the publish gate (Cut 4).
|
|
12
|
+
*/
|
|
13
|
+
export type Severity = 'error' | 'warn' | 'info';
|
|
14
|
+
/**
|
|
15
|
+
* One validation finding. Stable shape across all validators and stages.
|
|
16
|
+
*/
|
|
17
|
+
export interface Issue {
|
|
18
|
+
/** Stable identifier of the validator that produced this issue. */
|
|
19
|
+
validator: string;
|
|
20
|
+
severity: Severity;
|
|
21
|
+
/** Human-readable message. Author-facing. */
|
|
22
|
+
message: string;
|
|
23
|
+
/** Item path like `pages/home/page.json`. */
|
|
24
|
+
itemPath: string;
|
|
25
|
+
/** Content-tree path within the manifest, when applicable. */
|
|
26
|
+
contentPath?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional structured suppression hint — `Issue.suppressible: true`
|
|
29
|
+
* means a future "ignore this issue" mechanism would apply.
|
|
30
|
+
*/
|
|
31
|
+
suppressible?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stage-specific scope. Validators dispatch on `scope.kind` to read the right input.
|
|
35
|
+
*
|
|
36
|
+
* - `save-delta`: a single item (page or fragment) being saved, with before+after.
|
|
37
|
+
* - `background`: a single item being scanned (after the scanner has detected change).
|
|
38
|
+
* - `pre-publish`: the set of items being published, all together.
|
|
39
|
+
* - `cli`: site-wide; validator iterates everything.
|
|
40
|
+
*/
|
|
41
|
+
export type ValidatorScope = {
|
|
42
|
+
kind: 'save-delta';
|
|
43
|
+
item: SavedItem;
|
|
44
|
+
/** The on-disk manifest before this save (null when creating a new item). */
|
|
45
|
+
before: PageManifest | FragmentManifest | null;
|
|
46
|
+
/** The incoming manifest being saved. */
|
|
47
|
+
after: PageManifest | FragmentManifest;
|
|
48
|
+
} | {
|
|
49
|
+
kind: 'background';
|
|
50
|
+
item: SavedItem;
|
|
51
|
+
/**
|
|
52
|
+
* The current manifest read by the scanner. Pre-loaded so validators
|
|
53
|
+
* stay pure functions over (manifest, site) — no per-validator storage
|
|
54
|
+
* reads.
|
|
55
|
+
*/
|
|
56
|
+
manifest: PageManifest | FragmentManifest;
|
|
57
|
+
} | {
|
|
58
|
+
kind: 'pre-publish';
|
|
59
|
+
items: readonly SavedItem[];
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'cli';
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Identifies a page or fragment item. The validator framework treats them
|
|
65
|
+
* uniformly for stage dispatch; validators that only apply to one or the other
|
|
66
|
+
* branch on `kind`.
|
|
67
|
+
*/
|
|
68
|
+
export interface SavedItem {
|
|
69
|
+
kind: 'page' | 'fragment';
|
|
70
|
+
/** Logical name, e.g. `home`, `blog/[slug]`, `header`. */
|
|
71
|
+
name: string;
|
|
72
|
+
/** Filesystem path to the manifest, e.g. `pages/home/page.json`. */
|
|
73
|
+
itemPath: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Hook for cached rendered HTML output. Populated by Cut 3 (render-for-analysis);
|
|
77
|
+
* absent in Cut 1 (save-delta), so validators must guard against undefined.
|
|
78
|
+
*/
|
|
79
|
+
export interface RenderedOutputAccess {
|
|
80
|
+
htmlFor(item: SavedItem): Promise<string | null>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Inputs every validator receives. Stage-specific data lives in `scope`;
|
|
84
|
+
* validators that don't care about a stage simply don't include it in `stages`
|
|
85
|
+
* and won't be invoked.
|
|
86
|
+
*/
|
|
87
|
+
export interface ValidatorInput {
|
|
88
|
+
stage: ValidationStage;
|
|
89
|
+
site: Site;
|
|
90
|
+
contentRoot: ContentRoot;
|
|
91
|
+
storage: StorageProvider;
|
|
92
|
+
scope: ValidatorScope;
|
|
93
|
+
renderedOutput?: RenderedOutputAccess;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The validator contract. One implementation per validation rule.
|
|
97
|
+
*
|
|
98
|
+
* - `source` — package identity for diagnostics + audit + plugin-promotion.
|
|
99
|
+
* In-tree validators use `'gazetta'`; npm-distributed validators use their
|
|
100
|
+
* package name (`'@example/link-checker'`); site-local factories use
|
|
101
|
+
* `'site-local:{name}'`. Per design-plugins.md "source convention" + ADR-0009.
|
|
102
|
+
* - `name` — stable identifier referenced from issues and registry lookup.
|
|
103
|
+
* - `stages` — which lifecycle stages this validator runs at. Save-delta-only
|
|
104
|
+
* validators (most ref-existence checks) declare `['save-delta', 'background', 'pre-publish', 'cli']`
|
|
105
|
+
* so the same rule fires uniformly at every gate.
|
|
106
|
+
* - `defaultSeverity(stage)` — what severity issues from this validator have
|
|
107
|
+
* at the given stage. The same rule may be `error` at save-delta but `warn`
|
|
108
|
+
* in background to avoid false-positive blocks on accumulated debt.
|
|
109
|
+
* - `validate(input)` — run the rule. Never throws on validation failure;
|
|
110
|
+
* throws are reserved for infrastructure errors (storage failure, etc).
|
|
111
|
+
*/
|
|
112
|
+
export interface Validator {
|
|
113
|
+
readonly source: string;
|
|
114
|
+
readonly name: string;
|
|
115
|
+
readonly stages: readonly ValidationStage[];
|
|
116
|
+
defaultSeverity(stage: ValidationStage): Severity;
|
|
117
|
+
validate(input: ValidatorInput): Promise<Issue[]>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Helper — extract the components array from a manifest, defaulting to empty.
|
|
121
|
+
*/
|
|
122
|
+
export declare function manifestComponents(manifest: PageManifest | FragmentManifest | null): readonly ComponentEntry[];
|
|
123
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/validation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,KAAK,CAAA;AAEjF;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEhD;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,QAAQ,CAAA;IAClB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,6EAA6E;IAC7E,MAAM,EAAE,YAAY,GAAG,gBAAgB,GAAG,IAAI,CAAA;IAC9C,yCAAyC;IACzC,KAAK,EAAE,YAAY,GAAG,gBAAgB,CAAA;CACvC,GACD;IACE,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf;;;;OAIG;IACH,QAAQ,EAAE,YAAY,GAAG,gBAAgB,CAAA;CAC1C,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAAA;AAEnB;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CACjD;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,eAAe,CAAA;IACtB,IAAI,EAAE,IAAI,CAAA;IACV,WAAW,EAAE,WAAW,CAAA;IACxB,OAAO,EAAE,eAAe,CAAA;IACxB,KAAK,EAAE,cAAc,CAAA;IACrB,cAAc,CAAC,EAAE,oBAAoB,CAAA;CACtC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,QAAQ,CAAA;IACjD,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;CAClD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,cAAc,EAAE,CAE9G"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/validation/types.ts"],"names":[],"mappings":"AA8HA;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgD;IACjF,OAAO,QAAQ,EAAE,UAAU,IAAI,EAAE,CAAA;AACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility.d.ts","sourceRoot":"","sources":["../../../src/validation/validators/accessibility.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAS,SAAS,EAAkB,MAAM,aAAa,CAAA;AAiCnE,eAAO,MAAM,aAAa,EAAE,SAoC3B,CAAA"}
|