@actuate-media/cms-core 0.83.0 → 0.85.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/CHANGELOG.md +18 -0
- package/dist/api/route-helpers.d.ts +2 -0
- package/dist/api/route-helpers.d.ts.map +1 -1
- package/dist/api/route-helpers.js +119 -37
- package/dist/api/route-helpers.js.map +1 -1
- package/dist/config/types.d.ts +15 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/content/structured-data.d.ts +1 -0
- package/dist/content/structured-data.d.ts.map +1 -1
- package/dist/content/structured-data.js +1 -1
- package/dist/content/structured-data.js.map +1 -1
- package/dist/forms/index.d.ts +3 -0
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +3 -0
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/prefetch.d.ts +17 -0
- package/dist/forms/prefetch.d.ts.map +1 -0
- package/dist/forms/prefetch.js +36 -0
- package/dist/forms/prefetch.js.map +1 -0
- package/dist/forms/public-html.d.ts +22 -0
- package/dist/forms/public-html.d.ts.map +1 -0
- package/dist/forms/public-html.js +145 -0
- package/dist/forms/public-html.js.map +1 -0
- package/dist/forms/submission.d.ts +8 -0
- package/dist/forms/submission.d.ts.map +1 -1
- package/dist/forms/submission.js +3 -1
- package/dist/forms/submission.js.map +1 -1
- package/dist/forms/webmcp.d.ts +36 -0
- package/dist/forms/webmcp.d.ts.map +1 -0
- package/dist/forms/webmcp.js +67 -0
- package/dist/forms/webmcp.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/next-site.d.ts +29 -0
- package/dist/next-site.d.ts.map +1 -0
- package/dist/next-site.js +60 -0
- package/dist/next-site.js.map +1 -0
- package/dist/sections/index.d.ts +2 -0
- package/dist/sections/index.d.ts.map +1 -1
- package/dist/sections/index.js +1 -0
- package/dist/sections/index.js.map +1 -1
- package/dist/sections/registry.d.ts.map +1 -1
- package/dist/sections/registry.js +86 -0
- package/dist/sections/registry.js.map +1 -1
- package/dist/sections/types.d.ts +1 -1
- package/dist/sections/types.d.ts.map +1 -1
- package/dist/sections/validate.d.ts.map +1 -1
- package/dist/sections/validate.js +23 -0
- package/dist/sections/validate.js.map +1 -1
- package/dist/sections/widget-embed.d.ts +45 -0
- package/dist/sections/widget-embed.d.ts.map +1 -0
- package/dist/sections/widget-embed.js +129 -0
- package/dist/sections/widget-embed.js.map +1 -0
- package/dist/seo/page-meta.d.ts.map +1 -1
- package/dist/seo/page-meta.js +11 -0
- package/dist/seo/page-meta.js.map +1 -1
- package/dist/server-site.d.ts.map +1 -1
- package/dist/server-site.js +13 -0
- package/dist/server-site.js.map +1 -1
- package/dist/site.d.ts +6 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +6 -0
- package/dist/site.js.map +1 -1
- package/package.json +26 -1
- package/dist/__tests__/actions/document-crud.test.d.ts +0 -2
- package/dist/__tests__/actions/document-crud.test.d.ts.map +0 -1
- package/dist/__tests__/actions/document-crud.test.js +0 -442
- package/dist/__tests__/actions/document-crud.test.js.map +0 -1
- package/dist/__tests__/actions/seo-fields-update.test.d.ts +0 -2
- package/dist/__tests__/actions/seo-fields-update.test.d.ts.map +0 -1
- package/dist/__tests__/actions/seo-fields-update.test.js +0 -93
- package/dist/__tests__/actions/seo-fields-update.test.js.map +0 -1
- package/dist/__tests__/ai/ai.test.d.ts +0 -2
- package/dist/__tests__/ai/ai.test.d.ts.map +0 -1
- package/dist/__tests__/ai/ai.test.js +0 -266
- package/dist/__tests__/ai/ai.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice-alignment.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice-alignment.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice-alignment.test.js +0 -38
- package/dist/__tests__/ai/brand-voice-alignment.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice-analyze.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice-analyze.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice-analyze.test.js +0 -117
- package/dist/__tests__/ai/brand-voice-analyze.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice-document.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice-document.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice-document.test.js +0 -74
- package/dist/__tests__/ai/brand-voice-document.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice-fix.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice-fix.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice-fix.test.js +0 -34
- package/dist/__tests__/ai/brand-voice-fix.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice-sources.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice-sources.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice-sources.test.js +0 -14
- package/dist/__tests__/ai/brand-voice-sources.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice-structured.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice-structured.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice-structured.test.js +0 -49
- package/dist/__tests__/ai/brand-voice-structured.test.js.map +0 -1
- package/dist/__tests__/ai/brand-voice.test.d.ts +0 -2
- package/dist/__tests__/ai/brand-voice.test.d.ts.map +0 -1
- package/dist/__tests__/ai/brand-voice.test.js +0 -82
- package/dist/__tests__/ai/brand-voice.test.js.map +0 -1
- package/dist/__tests__/ai/content-writing-generate.test.d.ts +0 -2
- package/dist/__tests__/ai/content-writing-generate.test.d.ts.map +0 -1
- package/dist/__tests__/ai/content-writing-generate.test.js +0 -38
- package/dist/__tests__/ai/content-writing-generate.test.js.map +0 -1
- package/dist/__tests__/ai/resolve.test.d.ts +0 -2
- package/dist/__tests__/ai/resolve.test.d.ts.map +0 -1
- package/dist/__tests__/ai/resolve.test.js +0 -164
- package/dist/__tests__/ai/resolve.test.js.map +0 -1
- package/dist/__tests__/ai/runtime.test.d.ts +0 -2
- package/dist/__tests__/ai/runtime.test.d.ts.map +0 -1
- package/dist/__tests__/ai/runtime.test.js +0 -392
- package/dist/__tests__/ai/runtime.test.js.map +0 -1
- package/dist/__tests__/ai/sampling.test.d.ts +0 -2
- package/dist/__tests__/ai/sampling.test.d.ts.map +0 -1
- package/dist/__tests__/ai/sampling.test.js +0 -25
- package/dist/__tests__/ai/sampling.test.js.map +0 -1
- package/dist/__tests__/api/admin-contracts.test.d.ts +0 -2
- package/dist/__tests__/api/admin-contracts.test.d.ts.map +0 -1
- package/dist/__tests__/api/admin-contracts.test.js +0 -186
- package/dist/__tests__/api/admin-contracts.test.js.map +0 -1
- package/dist/__tests__/api/ai-crawlers.test.d.ts +0 -2
- package/dist/__tests__/api/ai-crawlers.test.d.ts.map +0 -1
- package/dist/__tests__/api/ai-crawlers.test.js +0 -194
- package/dist/__tests__/api/ai-crawlers.test.js.map +0 -1
- package/dist/__tests__/api/ai-quality.test.d.ts +0 -2
- package/dist/__tests__/api/ai-quality.test.d.ts.map +0 -1
- package/dist/__tests__/api/ai-quality.test.js +0 -721
- package/dist/__tests__/api/ai-quality.test.js.map +0 -1
- package/dist/__tests__/api/ai-status.test.d.ts +0 -2
- package/dist/__tests__/api/ai-status.test.d.ts.map +0 -1
- package/dist/__tests__/api/ai-status.test.js +0 -110
- package/dist/__tests__/api/ai-status.test.js.map +0 -1
- package/dist/__tests__/api/api-key-auth.test.d.ts +0 -2
- package/dist/__tests__/api/api-key-auth.test.d.ts.map +0 -1
- package/dist/__tests__/api/api-key-auth.test.js +0 -254
- package/dist/__tests__/api/api-key-auth.test.js.map +0 -1
- package/dist/__tests__/api/appearance-routes.test.d.ts +0 -2
- package/dist/__tests__/api/appearance-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/appearance-routes.test.js +0 -134
- package/dist/__tests__/api/appearance-routes.test.js.map +0 -1
- package/dist/__tests__/api/cache-headers.test.d.ts +0 -2
- package/dist/__tests__/api/cache-headers.test.d.ts.map +0 -1
- package/dist/__tests__/api/cache-headers.test.js +0 -135
- package/dist/__tests__/api/cache-headers.test.js.map +0 -1
- package/dist/__tests__/api/collection-introspection.test.d.ts +0 -2
- package/dist/__tests__/api/collection-introspection.test.d.ts.map +0 -1
- package/dist/__tests__/api/collection-introspection.test.js +0 -129
- package/dist/__tests__/api/collection-introspection.test.js.map +0 -1
- package/dist/__tests__/api/collection-read-access.test.d.ts +0 -2
- package/dist/__tests__/api/collection-read-access.test.d.ts.map +0 -1
- package/dist/__tests__/api/collection-read-access.test.js +0 -140
- package/dist/__tests__/api/collection-read-access.test.js.map +0 -1
- package/dist/__tests__/api/collections-ai-create.test.d.ts +0 -2
- package/dist/__tests__/api/collections-ai-create.test.d.ts.map +0 -1
- package/dist/__tests__/api/collections-ai-create.test.js +0 -313
- package/dist/__tests__/api/collections-ai-create.test.js.map +0 -1
- package/dist/__tests__/api/collections-discovery.test.d.ts +0 -2
- package/dist/__tests__/api/collections-discovery.test.d.ts.map +0 -1
- package/dist/__tests__/api/collections-discovery.test.js +0 -348
- package/dist/__tests__/api/collections-discovery.test.js.map +0 -1
- package/dist/__tests__/api/comments-routes.test.d.ts +0 -2
- package/dist/__tests__/api/comments-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/comments-routes.test.js +0 -266
- package/dist/__tests__/api/comments-routes.test.js.map +0 -1
- package/dist/__tests__/api/cron-routes.test.d.ts +0 -2
- package/dist/__tests__/api/cron-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/cron-routes.test.js +0 -67
- package/dist/__tests__/api/cron-routes.test.js.map +0 -1
- package/dist/__tests__/api/data-filters-routes.test.d.ts +0 -2
- package/dist/__tests__/api/data-filters-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/data-filters-routes.test.js +0 -131
- package/dist/__tests__/api/data-filters-routes.test.js.map +0 -1
- package/dist/__tests__/api/email-settings-routes.test.d.ts +0 -2
- package/dist/__tests__/api/email-settings-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/email-settings-routes.test.js +0 -240
- package/dist/__tests__/api/email-settings-routes.test.js.map +0 -1
- package/dist/__tests__/api/field-values-routes.test.d.ts +0 -2
- package/dist/__tests__/api/field-values-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/field-values-routes.test.js +0 -147
- package/dist/__tests__/api/field-values-routes.test.js.map +0 -1
- package/dist/__tests__/api/form-webhooks.test.d.ts +0 -2
- package/dist/__tests__/api/form-webhooks.test.d.ts.map +0 -1
- package/dist/__tests__/api/form-webhooks.test.js +0 -162
- package/dist/__tests__/api/form-webhooks.test.js.map +0 -1
- package/dist/__tests__/api/globals-routes.test.d.ts +0 -2
- package/dist/__tests__/api/globals-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/globals-routes.test.js +0 -100
- package/dist/__tests__/api/globals-routes.test.js.map +0 -1
- package/dist/__tests__/api/health.test.d.ts +0 -2
- package/dist/__tests__/api/health.test.d.ts.map +0 -1
- package/dist/__tests__/api/health.test.js +0 -144
- package/dist/__tests__/api/health.test.js.map +0 -1
- package/dist/__tests__/api/llms-txt.test.d.ts +0 -2
- package/dist/__tests__/api/llms-txt.test.d.ts.map +0 -1
- package/dist/__tests__/api/llms-txt.test.js +0 -423
- package/dist/__tests__/api/llms-txt.test.js.map +0 -1
- package/dist/__tests__/api/md-route.test.d.ts +0 -2
- package/dist/__tests__/api/md-route.test.d.ts.map +0 -1
- package/dist/__tests__/api/md-route.test.js +0 -106
- package/dist/__tests__/api/md-route.test.js.map +0 -1
- package/dist/__tests__/api/media-upload-storage.test.d.ts +0 -2
- package/dist/__tests__/api/media-upload-storage.test.d.ts.map +0 -1
- package/dist/__tests__/api/media-upload-storage.test.js +0 -171
- package/dist/__tests__/api/media-upload-storage.test.js.map +0 -1
- package/dist/__tests__/api/notifications-routes.test.d.ts +0 -2
- package/dist/__tests__/api/notifications-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/notifications-routes.test.js +0 -270
- package/dist/__tests__/api/notifications-routes.test.js.map +0 -1
- package/dist/__tests__/api/page-sections-routes.test.d.ts +0 -2
- package/dist/__tests__/api/page-sections-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/page-sections-routes.test.js +0 -501
- package/dist/__tests__/api/page-sections-routes.test.js.map +0 -1
- package/dist/__tests__/api/preview-and-scheduling.test.d.ts +0 -2
- package/dist/__tests__/api/preview-and-scheduling.test.d.ts.map +0 -1
- package/dist/__tests__/api/preview-and-scheduling.test.js +0 -479
- package/dist/__tests__/api/preview-and-scheduling.test.js.map +0 -1
- package/dist/__tests__/api/public-forms.test.d.ts +0 -2
- package/dist/__tests__/api/public-forms.test.d.ts.map +0 -1
- package/dist/__tests__/api/public-forms.test.js +0 -125
- package/dist/__tests__/api/public-forms.test.js.map +0 -1
- package/dist/__tests__/api/public-globals.test.d.ts +0 -2
- package/dist/__tests__/api/public-globals.test.d.ts.map +0 -1
- package/dist/__tests__/api/public-globals.test.js +0 -96
- package/dist/__tests__/api/public-globals.test.js.map +0 -1
- package/dist/__tests__/api/public-navigations.test.d.ts +0 -2
- package/dist/__tests__/api/public-navigations.test.d.ts.map +0 -1
- package/dist/__tests__/api/public-navigations.test.js +0 -77
- package/dist/__tests__/api/public-navigations.test.js.map +0 -1
- package/dist/__tests__/api/public-seo.test.d.ts +0 -2
- package/dist/__tests__/api/public-seo.test.d.ts.map +0 -1
- package/dist/__tests__/api/public-seo.test.js +0 -834
- package/dist/__tests__/api/public-seo.test.js.map +0 -1
- package/dist/__tests__/api/resolve-layout-bridge.test.d.ts +0 -2
- package/dist/__tests__/api/resolve-layout-bridge.test.d.ts.map +0 -1
- package/dist/__tests__/api/resolve-layout-bridge.test.js +0 -165
- package/dist/__tests__/api/resolve-layout-bridge.test.js.map +0 -1
- package/dist/__tests__/api/route-contracts.test.d.ts +0 -2
- package/dist/__tests__/api/route-contracts.test.d.ts.map +0 -1
- package/dist/__tests__/api/route-contracts.test.js +0 -466
- package/dist/__tests__/api/route-contracts.test.js.map +0 -1
- package/dist/__tests__/api/security-routes.test.d.ts +0 -2
- package/dist/__tests__/api/security-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/security-routes.test.js +0 -212
- package/dist/__tests__/api/security-routes.test.js.map +0 -1
- package/dist/__tests__/api/seo-read-access.test.d.ts +0 -2
- package/dist/__tests__/api/seo-read-access.test.d.ts.map +0 -1
- package/dist/__tests__/api/seo-read-access.test.js +0 -101
- package/dist/__tests__/api/seo-read-access.test.js.map +0 -1
- package/dist/__tests__/api/seo-summary-ssrf.test.d.ts +0 -2
- package/dist/__tests__/api/seo-summary-ssrf.test.d.ts.map +0 -1
- package/dist/__tests__/api/seo-summary-ssrf.test.js +0 -80
- package/dist/__tests__/api/seo-summary-ssrf.test.js.map +0 -1
- package/dist/__tests__/api/sitemap-pagination.test.d.ts +0 -2
- package/dist/__tests__/api/sitemap-pagination.test.d.ts.map +0 -1
- package/dist/__tests__/api/sitemap-pagination.test.js +0 -100
- package/dist/__tests__/api/sitemap-pagination.test.js.map +0 -1
- package/dist/__tests__/api/stats-collection-filter.test.d.ts +0 -2
- package/dist/__tests__/api/stats-collection-filter.test.d.ts.map +0 -1
- package/dist/__tests__/api/stats-collection-filter.test.js +0 -190
- package/dist/__tests__/api/stats-collection-filter.test.js.map +0 -1
- package/dist/__tests__/api/stats-routes.test.d.ts +0 -2
- package/dist/__tests__/api/stats-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/stats-routes.test.js +0 -251
- package/dist/__tests__/api/stats-routes.test.js.map +0 -1
- package/dist/__tests__/api/stats-seo-cache.test.d.ts +0 -2
- package/dist/__tests__/api/stats-seo-cache.test.d.ts.map +0 -1
- package/dist/__tests__/api/stats-seo-cache.test.js +0 -96
- package/dist/__tests__/api/stats-seo-cache.test.js.map +0 -1
- package/dist/__tests__/api/totp-login.test.d.ts +0 -2
- package/dist/__tests__/api/totp-login.test.d.ts.map +0 -1
- package/dist/__tests__/api/totp-login.test.js +0 -115
- package/dist/__tests__/api/totp-login.test.js.map +0 -1
- package/dist/__tests__/api/updates-routes.test.d.ts +0 -2
- package/dist/__tests__/api/updates-routes.test.d.ts.map +0 -1
- package/dist/__tests__/api/updates-routes.test.js +0 -248
- package/dist/__tests__/api/updates-routes.test.js.map +0 -1
- package/dist/__tests__/api/users-detail.test.d.ts +0 -2
- package/dist/__tests__/api/users-detail.test.d.ts.map +0 -1
- package/dist/__tests__/api/users-detail.test.js +0 -401
- package/dist/__tests__/api/users-detail.test.js.map +0 -1
- package/dist/__tests__/api/users-invite.test.d.ts +0 -2
- package/dist/__tests__/api/users-invite.test.d.ts.map +0 -1
- package/dist/__tests__/api/users-invite.test.js +0 -221
- package/dist/__tests__/api/users-invite.test.js.map +0 -1
- package/dist/__tests__/api/users-search.test.d.ts +0 -2
- package/dist/__tests__/api/users-search.test.d.ts.map +0 -1
- package/dist/__tests__/api/users-search.test.js +0 -182
- package/dist/__tests__/api/users-search.test.js.map +0 -1
- package/dist/__tests__/appearance/appearance.test.d.ts +0 -2
- package/dist/__tests__/appearance/appearance.test.d.ts.map +0 -1
- package/dist/__tests__/appearance/appearance.test.js +0 -287
- package/dist/__tests__/appearance/appearance.test.js.map +0 -1
- package/dist/__tests__/appearance/favicon-icon.test.d.ts +0 -2
- package/dist/__tests__/appearance/favicon-icon.test.d.ts.map +0 -1
- package/dist/__tests__/appearance/favicon-icon.test.js +0 -12
- package/dist/__tests__/appearance/favicon-icon.test.js.map +0 -1
- package/dist/__tests__/auth/invites.test.d.ts +0 -2
- package/dist/__tests__/auth/invites.test.d.ts.map +0 -1
- package/dist/__tests__/auth/invites.test.js +0 -181
- package/dist/__tests__/auth/invites.test.js.map +0 -1
- package/dist/__tests__/auth/oauth.test.d.ts +0 -2
- package/dist/__tests__/auth/oauth.test.d.ts.map +0 -1
- package/dist/__tests__/auth/oauth.test.js +0 -408
- package/dist/__tests__/auth/oauth.test.js.map +0 -1
- package/dist/__tests__/auth/password.test.d.ts +0 -2
- package/dist/__tests__/auth/password.test.d.ts.map +0 -1
- package/dist/__tests__/auth/password.test.js +0 -226
- package/dist/__tests__/auth/password.test.js.map +0 -1
- package/dist/__tests__/auth/reset.test.d.ts +0 -2
- package/dist/__tests__/auth/reset.test.d.ts.map +0 -1
- package/dist/__tests__/auth/reset.test.js +0 -355
- package/dist/__tests__/auth/reset.test.js.map +0 -1
- package/dist/__tests__/auth/roles.test.d.ts +0 -2
- package/dist/__tests__/auth/roles.test.d.ts.map +0 -1
- package/dist/__tests__/auth/roles.test.js +0 -60
- package/dist/__tests__/auth/roles.test.js.map +0 -1
- package/dist/__tests__/auth/session.test.d.ts +0 -2
- package/dist/__tests__/auth/session.test.d.ts.map +0 -1
- package/dist/__tests__/auth/session.test.js +0 -119
- package/dist/__tests__/auth/session.test.js.map +0 -1
- package/dist/__tests__/auth/team.test.d.ts +0 -2
- package/dist/__tests__/auth/team.test.d.ts.map +0 -1
- package/dist/__tests__/auth/team.test.js +0 -154
- package/dist/__tests__/auth/team.test.js.map +0 -1
- package/dist/__tests__/auth/totp.test.d.ts +0 -2
- package/dist/__tests__/auth/totp.test.d.ts.map +0 -1
- package/dist/__tests__/auth/totp.test.js +0 -52
- package/dist/__tests__/auth/totp.test.js.map +0 -1
- package/dist/__tests__/auth/user-admin.test.d.ts +0 -2
- package/dist/__tests__/auth/user-admin.test.d.ts.map +0 -1
- package/dist/__tests__/auth/user-admin.test.js +0 -200
- package/dist/__tests__/auth/user-admin.test.js.map +0 -1
- package/dist/__tests__/billing/stripe-meter.test.d.ts +0 -2
- package/dist/__tests__/billing/stripe-meter.test.d.ts.map +0 -1
- package/dist/__tests__/billing/stripe-meter.test.js +0 -86
- package/dist/__tests__/billing/stripe-meter.test.js.map +0 -1
- package/dist/__tests__/codegen/generate-types.test.d.ts +0 -2
- package/dist/__tests__/codegen/generate-types.test.d.ts.map +0 -1
- package/dist/__tests__/codegen/generate-types.test.js +0 -173
- package/dist/__tests__/codegen/generate-types.test.js.map +0 -1
- package/dist/__tests__/collections/presets.test.d.ts +0 -2
- package/dist/__tests__/collections/presets.test.d.ts.map +0 -1
- package/dist/__tests__/collections/presets.test.js +0 -184
- package/dist/__tests__/collections/presets.test.js.map +0 -1
- package/dist/__tests__/config/runtime.test.d.ts +0 -2
- package/dist/__tests__/config/runtime.test.d.ts.map +0 -1
- package/dist/__tests__/config/runtime.test.js +0 -65
- package/dist/__tests__/config/runtime.test.js.map +0 -1
- package/dist/__tests__/content/slug.test.d.ts +0 -2
- package/dist/__tests__/content/slug.test.d.ts.map +0 -1
- package/dist/__tests__/content/slug.test.js +0 -68
- package/dist/__tests__/content/slug.test.js.map +0 -1
- package/dist/__tests__/content-health/scanner.test.d.ts +0 -2
- package/dist/__tests__/content-health/scanner.test.d.ts.map +0 -1
- package/dist/__tests__/content-health/scanner.test.js +0 -151
- package/dist/__tests__/content-health/scanner.test.js.map +0 -1
- package/dist/__tests__/cron/cron.test.d.ts +0 -2
- package/dist/__tests__/cron/cron.test.d.ts.map +0 -1
- package/dist/__tests__/cron/cron.test.js +0 -340
- package/dist/__tests__/cron/cron.test.js.map +0 -1
- package/dist/__tests__/db/model-types-freshness.test.d.ts +0 -2
- package/dist/__tests__/db/model-types-freshness.test.d.ts.map +0 -1
- package/dist/__tests__/db/model-types-freshness.test.js +0 -46
- package/dist/__tests__/db/model-types-freshness.test.js.map +0 -1
- package/dist/__tests__/diagnostics/api-metrics.test.d.ts +0 -2
- package/dist/__tests__/diagnostics/api-metrics.test.d.ts.map +0 -1
- package/dist/__tests__/diagnostics/api-metrics.test.js +0 -153
- package/dist/__tests__/diagnostics/api-metrics.test.js.map +0 -1
- package/dist/__tests__/diagnostics/env.test.d.ts +0 -2
- package/dist/__tests__/diagnostics/env.test.d.ts.map +0 -1
- package/dist/__tests__/diagnostics/env.test.js +0 -247
- package/dist/__tests__/diagnostics/env.test.js.map +0 -1
- package/dist/__tests__/diagnostics/logger.test.d.ts +0 -2
- package/dist/__tests__/diagnostics/logger.test.d.ts.map +0 -1
- package/dist/__tests__/diagnostics/logger.test.js +0 -111
- package/dist/__tests__/diagnostics/logger.test.js.map +0 -1
- package/dist/__tests__/diagnostics/sentry.test.d.ts +0 -2
- package/dist/__tests__/diagnostics/sentry.test.d.ts.map +0 -1
- package/dist/__tests__/diagnostics/sentry.test.js +0 -60
- package/dist/__tests__/diagnostics/sentry.test.js.map +0 -1
- package/dist/__tests__/email/resolve.test.d.ts +0 -2
- package/dist/__tests__/email/resolve.test.d.ts.map +0 -1
- package/dist/__tests__/email/resolve.test.js +0 -90
- package/dist/__tests__/email/resolve.test.js.map +0 -1
- package/dist/__tests__/email/sender.test.d.ts +0 -2
- package/dist/__tests__/email/sender.test.d.ts.map +0 -1
- package/dist/__tests__/email/sender.test.js +0 -33
- package/dist/__tests__/email/sender.test.js.map +0 -1
- package/dist/__tests__/email/settings-store.test.d.ts +0 -2
- package/dist/__tests__/email/settings-store.test.d.ts.map +0 -1
- package/dist/__tests__/email/settings-store.test.js +0 -149
- package/dist/__tests__/email/settings-store.test.js.map +0 -1
- package/dist/__tests__/fields/component-block.test.d.ts +0 -2
- package/dist/__tests__/fields/component-block.test.d.ts.map +0 -1
- package/dist/__tests__/fields/component-block.test.js +0 -129
- package/dist/__tests__/fields/component-block.test.js.map +0 -1
- package/dist/__tests__/fields/presets.test.d.ts +0 -2
- package/dist/__tests__/fields/presets.test.d.ts.map +0 -1
- package/dist/__tests__/fields/presets.test.js +0 -99
- package/dist/__tests__/fields/presets.test.js.map +0 -1
- package/dist/__tests__/fields/relations.test.d.ts +0 -2
- package/dist/__tests__/fields/relations.test.d.ts.map +0 -1
- package/dist/__tests__/fields/relations.test.js +0 -297
- package/dist/__tests__/fields/relations.test.js.map +0 -1
- package/dist/__tests__/forms/client-validation.test.d.ts +0 -2
- package/dist/__tests__/forms/client-validation.test.d.ts.map +0 -1
- package/dist/__tests__/forms/client-validation.test.js +0 -98
- package/dist/__tests__/forms/client-validation.test.js.map +0 -1
- package/dist/__tests__/forms/encryption.test.d.ts +0 -2
- package/dist/__tests__/forms/encryption.test.d.ts.map +0 -1
- package/dist/__tests__/forms/encryption.test.js +0 -84
- package/dist/__tests__/forms/encryption.test.js.map +0 -1
- package/dist/__tests__/forms/entries-export.test.d.ts +0 -2
- package/dist/__tests__/forms/entries-export.test.d.ts.map +0 -1
- package/dist/__tests__/forms/entries-export.test.js +0 -69
- package/dist/__tests__/forms/entries-export.test.js.map +0 -1
- package/dist/__tests__/forms/forms-service.test.d.ts +0 -2
- package/dist/__tests__/forms/forms-service.test.d.ts.map +0 -1
- package/dist/__tests__/forms/forms-service.test.js +0 -193
- package/dist/__tests__/forms/forms-service.test.js.map +0 -1
- package/dist/__tests__/forms/notify.test.d.ts +0 -2
- package/dist/__tests__/forms/notify.test.d.ts.map +0 -1
- package/dist/__tests__/forms/notify.test.js +0 -114
- package/dist/__tests__/forms/notify.test.js.map +0 -1
- package/dist/__tests__/forms/spam.test.d.ts +0 -2
- package/dist/__tests__/forms/spam.test.d.ts.map +0 -1
- package/dist/__tests__/forms/spam.test.js +0 -115
- package/dist/__tests__/forms/spam.test.js.map +0 -1
- package/dist/__tests__/forms/submission-files.test.d.ts +0 -2
- package/dist/__tests__/forms/submission-files.test.d.ts.map +0 -1
- package/dist/__tests__/forms/submission-files.test.js +0 -65
- package/dist/__tests__/forms/submission-files.test.js.map +0 -1
- package/dist/__tests__/forms/submission-pipeline.test.d.ts +0 -2
- package/dist/__tests__/forms/submission-pipeline.test.d.ts.map +0 -1
- package/dist/__tests__/forms/submission-pipeline.test.js +0 -131
- package/dist/__tests__/forms/submission-pipeline.test.js.map +0 -1
- package/dist/__tests__/forms/submission-validation.test.d.ts +0 -2
- package/dist/__tests__/forms/submission-validation.test.d.ts.map +0 -1
- package/dist/__tests__/forms/submission-validation.test.js +0 -108
- package/dist/__tests__/forms/submission-validation.test.js.map +0 -1
- package/dist/__tests__/forms/webhooks.test.d.ts +0 -2
- package/dist/__tests__/forms/webhooks.test.d.ts.map +0 -1
- package/dist/__tests__/forms/webhooks.test.js +0 -203
- package/dist/__tests__/forms/webhooks.test.js.map +0 -1
- package/dist/__tests__/media/seo.test.d.ts +0 -2
- package/dist/__tests__/media/seo.test.d.ts.map +0 -1
- package/dist/__tests__/media/seo.test.js +0 -186
- package/dist/__tests__/media/seo.test.js.map +0 -1
- package/dist/__tests__/middleware.test.d.ts +0 -2
- package/dist/__tests__/middleware.test.d.ts.map +0 -1
- package/dist/__tests__/middleware.test.js +0 -127
- package/dist/__tests__/middleware.test.js.map +0 -1
- package/dist/__tests__/next.test.d.ts +0 -2
- package/dist/__tests__/next.test.d.ts.map +0 -1
- package/dist/__tests__/next.test.js +0 -118
- package/dist/__tests__/next.test.js.map +0 -1
- package/dist/__tests__/plan/features.test.d.ts +0 -2
- package/dist/__tests__/plan/features.test.d.ts.map +0 -1
- package/dist/__tests__/plan/features.test.js +0 -35
- package/dist/__tests__/plan/features.test.js.map +0 -1
- package/dist/__tests__/preview-event-bus.test.d.ts +0 -2
- package/dist/__tests__/preview-event-bus.test.d.ts.map +0 -1
- package/dist/__tests__/preview-event-bus.test.js +0 -89
- package/dist/__tests__/preview-event-bus.test.js.map +0 -1
- package/dist/__tests__/preview-sse-stream.test.d.ts +0 -2
- package/dist/__tests__/preview-sse-stream.test.d.ts.map +0 -1
- package/dist/__tests__/preview-sse-stream.test.js +0 -117
- package/dist/__tests__/preview-sse-stream.test.js.map +0 -1
- package/dist/__tests__/preview.test.d.ts +0 -2
- package/dist/__tests__/preview.test.d.ts.map +0 -1
- package/dist/__tests__/preview.test.js +0 -71
- package/dist/__tests__/preview.test.js.map +0 -1
- package/dist/__tests__/realtime/comments.test.d.ts +0 -2
- package/dist/__tests__/realtime/comments.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/comments.test.js +0 -508
- package/dist/__tests__/realtime/comments.test.js.map +0 -1
- package/dist/__tests__/realtime/gateway-ws-integration.test.d.ts +0 -2
- package/dist/__tests__/realtime/gateway-ws-integration.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/gateway-ws-integration.test.js +0 -170
- package/dist/__tests__/realtime/gateway-ws-integration.test.js.map +0 -1
- package/dist/__tests__/realtime/gateway.test.d.ts +0 -2
- package/dist/__tests__/realtime/gateway.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/gateway.test.js +0 -402
- package/dist/__tests__/realtime/gateway.test.js.map +0 -1
- package/dist/__tests__/realtime/notification-bus.test.d.ts +0 -2
- package/dist/__tests__/realtime/notification-bus.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/notification-bus.test.js +0 -79
- package/dist/__tests__/realtime/notification-bus.test.js.map +0 -1
- package/dist/__tests__/realtime/notification-stream.test.d.ts +0 -2
- package/dist/__tests__/realtime/notification-stream.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/notification-stream.test.js +0 -157
- package/dist/__tests__/realtime/notification-stream.test.js.map +0 -1
- package/dist/__tests__/realtime/notifications.test.d.ts +0 -2
- package/dist/__tests__/realtime/notifications.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/notifications.test.js +0 -330
- package/dist/__tests__/realtime/notifications.test.js.map +0 -1
- package/dist/__tests__/realtime/persistence.test.d.ts +0 -2
- package/dist/__tests__/realtime/persistence.test.d.ts.map +0 -1
- package/dist/__tests__/realtime/persistence.test.js +0 -124
- package/dist/__tests__/realtime/persistence.test.js.map +0 -1
- package/dist/__tests__/redirects/auto-301.test.d.ts +0 -2
- package/dist/__tests__/redirects/auto-301.test.d.ts.map +0 -1
- package/dist/__tests__/redirects/auto-301.test.js +0 -172
- package/dist/__tests__/redirects/auto-301.test.js.map +0 -1
- package/dist/__tests__/redirects/graph.test.d.ts +0 -2
- package/dist/__tests__/redirects/graph.test.d.ts.map +0 -1
- package/dist/__tests__/redirects/graph.test.js +0 -104
- package/dist/__tests__/redirects/graph.test.js.map +0 -1
- package/dist/__tests__/redirects/suggest.test.d.ts +0 -2
- package/dist/__tests__/redirects/suggest.test.d.ts.map +0 -1
- package/dist/__tests__/redirects/suggest.test.js +0 -28
- package/dist/__tests__/redirects/suggest.test.js.map +0 -1
- package/dist/__tests__/scheduling/scheduling.test.d.ts +0 -2
- package/dist/__tests__/scheduling/scheduling.test.d.ts.map +0 -1
- package/dist/__tests__/scheduling/scheduling.test.js +0 -110
- package/dist/__tests__/scheduling/scheduling.test.js.map +0 -1
- package/dist/__tests__/schema-preview-features.test.d.ts +0 -2
- package/dist/__tests__/schema-preview-features.test.d.ts.map +0 -1
- package/dist/__tests__/schema-preview-features.test.js +0 -42
- package/dist/__tests__/schema-preview-features.test.js.map +0 -1
- package/dist/__tests__/sections/sections-migrate.test.d.ts +0 -2
- package/dist/__tests__/sections/sections-migrate.test.d.ts.map +0 -1
- package/dist/__tests__/sections/sections-migrate.test.js +0 -145
- package/dist/__tests__/sections/sections-migrate.test.js.map +0 -1
- package/dist/__tests__/security/access.test.d.ts +0 -2
- package/dist/__tests__/security/access.test.d.ts.map +0 -1
- package/dist/__tests__/security/access.test.js +0 -181
- package/dist/__tests__/security/access.test.js.map +0 -1
- package/dist/__tests__/security/api-key-enhanced.test.d.ts +0 -2
- package/dist/__tests__/security/api-key-enhanced.test.d.ts.map +0 -1
- package/dist/__tests__/security/api-key-enhanced.test.js +0 -110
- package/dist/__tests__/security/api-key-enhanced.test.js.map +0 -1
- package/dist/__tests__/security/audit.test.d.ts +0 -2
- package/dist/__tests__/security/audit.test.d.ts.map +0 -1
- package/dist/__tests__/security/audit.test.js +0 -50
- package/dist/__tests__/security/audit.test.js.map +0 -1
- package/dist/__tests__/security/center.test.d.ts +0 -2
- package/dist/__tests__/security/center.test.d.ts.map +0 -1
- package/dist/__tests__/security/center.test.js +0 -226
- package/dist/__tests__/security/center.test.js.map +0 -1
- package/dist/__tests__/security/client-ip.test.d.ts +0 -2
- package/dist/__tests__/security/client-ip.test.d.ts.map +0 -1
- package/dist/__tests__/security/client-ip.test.js +0 -37
- package/dist/__tests__/security/client-ip.test.js.map +0 -1
- package/dist/__tests__/security/csrf.test.d.ts +0 -2
- package/dist/__tests__/security/csrf.test.d.ts.map +0 -1
- package/dist/__tests__/security/csrf.test.js +0 -40
- package/dist/__tests__/security/csrf.test.js.map +0 -1
- package/dist/__tests__/security/encrypted-fields.test.d.ts +0 -2
- package/dist/__tests__/security/encrypted-fields.test.d.ts.map +0 -1
- package/dist/__tests__/security/encrypted-fields.test.js +0 -60
- package/dist/__tests__/security/encrypted-fields.test.js.map +0 -1
- package/dist/__tests__/security/ip-allowlist.test.d.ts +0 -2
- package/dist/__tests__/security/ip-allowlist.test.d.ts.map +0 -1
- package/dist/__tests__/security/ip-allowlist.test.js +0 -40
- package/dist/__tests__/security/ip-allowlist.test.js.map +0 -1
- package/dist/__tests__/security/rate-limit.test.d.ts +0 -2
- package/dist/__tests__/security/rate-limit.test.d.ts.map +0 -1
- package/dist/__tests__/security/rate-limit.test.js +0 -199
- package/dist/__tests__/security/rate-limit.test.js.map +0 -1
- package/dist/__tests__/security/reauth.test.d.ts +0 -2
- package/dist/__tests__/security/reauth.test.d.ts.map +0 -1
- package/dist/__tests__/security/reauth.test.js +0 -30
- package/dist/__tests__/security/reauth.test.js.map +0 -1
- package/dist/__tests__/security/redact.test.d.ts +0 -2
- package/dist/__tests__/security/redact.test.d.ts.map +0 -1
- package/dist/__tests__/security/redact.test.js +0 -31
- package/dist/__tests__/security/redact.test.js.map +0 -1
- package/dist/__tests__/security/safe-fetch.test.d.ts +0 -2
- package/dist/__tests__/security/safe-fetch.test.d.ts.map +0 -1
- package/dist/__tests__/security/safe-fetch.test.js +0 -97
- package/dist/__tests__/security/safe-fetch.test.js.map +0 -1
- package/dist/__tests__/security/sanitize-document.test.d.ts +0 -2
- package/dist/__tests__/security/sanitize-document.test.d.ts.map +0 -1
- package/dist/__tests__/security/sanitize-document.test.js +0 -146
- package/dist/__tests__/security/sanitize-document.test.js.map +0 -1
- package/dist/__tests__/security/sanitize.test.d.ts +0 -2
- package/dist/__tests__/security/sanitize.test.d.ts.map +0 -1
- package/dist/__tests__/security/sanitize.test.js +0 -75
- package/dist/__tests__/security/sanitize.test.js.map +0 -1
- package/dist/__tests__/security/secret-storage.test.d.ts +0 -2
- package/dist/__tests__/security/secret-storage.test.d.ts.map +0 -1
- package/dist/__tests__/security/secret-storage.test.js +0 -42
- package/dist/__tests__/security/secret-storage.test.js.map +0 -1
- package/dist/__tests__/security/ssrf.test.d.ts +0 -2
- package/dist/__tests__/security/ssrf.test.d.ts.map +0 -1
- package/dist/__tests__/security/ssrf.test.js +0 -209
- package/dist/__tests__/security/ssrf.test.js.map +0 -1
- package/dist/__tests__/security/upload-magic.test.d.ts +0 -2
- package/dist/__tests__/security/upload-magic.test.d.ts.map +0 -1
- package/dist/__tests__/security/upload-magic.test.js +0 -55
- package/dist/__tests__/security/upload-magic.test.js.map +0 -1
- package/dist/__tests__/seo/ai-bots.test.d.ts +0 -2
- package/dist/__tests__/seo/ai-bots.test.d.ts.map +0 -1
- package/dist/__tests__/seo/ai-bots.test.js +0 -92
- package/dist/__tests__/seo/ai-bots.test.js.map +0 -1
- package/dist/__tests__/seo/alt-text.test.d.ts +0 -2
- package/dist/__tests__/seo/alt-text.test.d.ts.map +0 -1
- package/dist/__tests__/seo/alt-text.test.js +0 -47
- package/dist/__tests__/seo/alt-text.test.js.map +0 -1
- package/dist/__tests__/seo/analysis-markdown.test.d.ts +0 -2
- package/dist/__tests__/seo/analysis-markdown.test.d.ts.map +0 -1
- package/dist/__tests__/seo/analysis-markdown.test.js +0 -57
- package/dist/__tests__/seo/analysis-markdown.test.js.map +0 -1
- package/dist/__tests__/seo/audit-engine.test.d.ts +0 -2
- package/dist/__tests__/seo/audit-engine.test.d.ts.map +0 -1
- package/dist/__tests__/seo/audit-engine.test.js +0 -181
- package/dist/__tests__/seo/audit-engine.test.js.map +0 -1
- package/dist/__tests__/seo/audit-runner.test.d.ts +0 -2
- package/dist/__tests__/seo/audit-runner.test.d.ts.map +0 -1
- package/dist/__tests__/seo/audit-runner.test.js +0 -204
- package/dist/__tests__/seo/audit-runner.test.js.map +0 -1
- package/dist/__tests__/seo/audit-signals.test.d.ts +0 -2
- package/dist/__tests__/seo/audit-signals.test.d.ts.map +0 -1
- package/dist/__tests__/seo/audit-signals.test.js +0 -30
- package/dist/__tests__/seo/audit-signals.test.js.map +0 -1
- package/dist/__tests__/seo/config-store.test.d.ts +0 -2
- package/dist/__tests__/seo/config-store.test.d.ts.map +0 -1
- package/dist/__tests__/seo/config-store.test.js +0 -31
- package/dist/__tests__/seo/config-store.test.js.map +0 -1
- package/dist/__tests__/seo/content-markdown.test.d.ts +0 -2
- package/dist/__tests__/seo/content-markdown.test.d.ts.map +0 -1
- package/dist/__tests__/seo/content-markdown.test.js +0 -124
- package/dist/__tests__/seo/content-markdown.test.js.map +0 -1
- package/dist/__tests__/seo/effective-meta.test.d.ts +0 -2
- package/dist/__tests__/seo/effective-meta.test.d.ts.map +0 -1
- package/dist/__tests__/seo/effective-meta.test.js +0 -58
- package/dist/__tests__/seo/effective-meta.test.js.map +0 -1
- package/dist/__tests__/seo/feeds.test.d.ts +0 -2
- package/dist/__tests__/seo/feeds.test.d.ts.map +0 -1
- package/dist/__tests__/seo/feeds.test.js +0 -61
- package/dist/__tests__/seo/feeds.test.js.map +0 -1
- package/dist/__tests__/seo/fix-brief-export.test.d.ts +0 -2
- package/dist/__tests__/seo/fix-brief-export.test.d.ts.map +0 -1
- package/dist/__tests__/seo/fix-brief-export.test.js +0 -153
- package/dist/__tests__/seo/fix-brief-export.test.js.map +0 -1
- package/dist/__tests__/seo/freshness.test.d.ts +0 -2
- package/dist/__tests__/seo/freshness.test.d.ts.map +0 -1
- package/dist/__tests__/seo/freshness.test.js +0 -89
- package/dist/__tests__/seo/freshness.test.js.map +0 -1
- package/dist/__tests__/seo/index-status.test.d.ts +0 -2
- package/dist/__tests__/seo/index-status.test.d.ts.map +0 -1
- package/dist/__tests__/seo/index-status.test.js +0 -140
- package/dist/__tests__/seo/index-status.test.js.map +0 -1
- package/dist/__tests__/seo/internal-collections.test.d.ts +0 -2
- package/dist/__tests__/seo/internal-collections.test.d.ts.map +0 -1
- package/dist/__tests__/seo/internal-collections.test.js +0 -27
- package/dist/__tests__/seo/internal-collections.test.js.map +0 -1
- package/dist/__tests__/seo/issue-batch-briefs.test.d.ts +0 -2
- package/dist/__tests__/seo/issue-batch-briefs.test.d.ts.map +0 -1
- package/dist/__tests__/seo/issue-batch-briefs.test.js +0 -64
- package/dist/__tests__/seo/issue-batch-briefs.test.js.map +0 -1
- package/dist/__tests__/seo/issue-content-brief.test.d.ts +0 -2
- package/dist/__tests__/seo/issue-content-brief.test.d.ts.map +0 -1
- package/dist/__tests__/seo/issue-content-brief.test.js +0 -107
- package/dist/__tests__/seo/issue-content-brief.test.js.map +0 -1
- package/dist/__tests__/seo/issue-content-research.test.d.ts +0 -2
- package/dist/__tests__/seo/issue-content-research.test.d.ts.map +0 -1
- package/dist/__tests__/seo/issue-content-research.test.js +0 -114
- package/dist/__tests__/seo/issue-content-research.test.js.map +0 -1
- package/dist/__tests__/seo/issue-fix-ai.test.d.ts +0 -2
- package/dist/__tests__/seo/issue-fix-ai.test.d.ts.map +0 -1
- package/dist/__tests__/seo/issue-fix-ai.test.js +0 -96
- package/dist/__tests__/seo/issue-fix-ai.test.js.map +0 -1
- package/dist/__tests__/seo/issue-fix-orchestrator.test.d.ts +0 -2
- package/dist/__tests__/seo/issue-fix-orchestrator.test.d.ts.map +0 -1
- package/dist/__tests__/seo/issue-fix-orchestrator.test.js +0 -48
- package/dist/__tests__/seo/issue-fix-orchestrator.test.js.map +0 -1
- package/dist/__tests__/seo/issue-fix.test.d.ts +0 -2
- package/dist/__tests__/seo/issue-fix.test.d.ts.map +0 -1
- package/dist/__tests__/seo/issue-fix.test.js +0 -98
- package/dist/__tests__/seo/issue-fix.test.js.map +0 -1
- package/dist/__tests__/seo/llms-sanitize.test.d.ts +0 -2
- package/dist/__tests__/seo/llms-sanitize.test.d.ts.map +0 -1
- package/dist/__tests__/seo/llms-sanitize.test.js +0 -74
- package/dist/__tests__/seo/llms-sanitize.test.js.map +0 -1
- package/dist/__tests__/seo/meta-tags-alternates.test.d.ts +0 -2
- package/dist/__tests__/seo/meta-tags-alternates.test.d.ts.map +0 -1
- package/dist/__tests__/seo/meta-tags-alternates.test.js +0 -52
- package/dist/__tests__/seo/meta-tags-alternates.test.js.map +0 -1
- package/dist/__tests__/seo/migrate-meta.test.d.ts +0 -2
- package/dist/__tests__/seo/migrate-meta.test.d.ts.map +0 -1
- package/dist/__tests__/seo/migrate-meta.test.js +0 -75
- package/dist/__tests__/seo/migrate-meta.test.js.map +0 -1
- package/dist/__tests__/seo/migrate-schema.test.d.ts +0 -2
- package/dist/__tests__/seo/migrate-schema.test.d.ts.map +0 -1
- package/dist/__tests__/seo/migrate-schema.test.js +0 -97
- package/dist/__tests__/seo/migrate-schema.test.js.map +0 -1
- package/dist/__tests__/seo/page-meta.test.d.ts +0 -2
- package/dist/__tests__/seo/page-meta.test.d.ts.map +0 -1
- package/dist/__tests__/seo/page-meta.test.js +0 -452
- package/dist/__tests__/seo/page-meta.test.js.map +0 -1
- package/dist/__tests__/seo/resolve-path.test.d.ts +0 -2
- package/dist/__tests__/seo/resolve-path.test.d.ts.map +0 -1
- package/dist/__tests__/seo/resolve-path.test.js +0 -46
- package/dist/__tests__/seo/resolve-path.test.js.map +0 -1
- package/dist/__tests__/seo/robots.test.d.ts +0 -2
- package/dist/__tests__/seo/robots.test.d.ts.map +0 -1
- package/dist/__tests__/seo/robots.test.js +0 -72
- package/dist/__tests__/seo/robots.test.js.map +0 -1
- package/dist/__tests__/seo/schema-sync.test.d.ts +0 -2
- package/dist/__tests__/seo/schema-sync.test.d.ts.map +0 -1
- package/dist/__tests__/seo/schema-sync.test.js +0 -59
- package/dist/__tests__/seo/schema-sync.test.js.map +0 -1
- package/dist/__tests__/seo/score.test.d.ts +0 -2
- package/dist/__tests__/seo/score.test.d.ts.map +0 -1
- package/dist/__tests__/seo/score.test.js +0 -152
- package/dist/__tests__/seo/score.test.js.map +0 -1
- package/dist/__tests__/seo/settings-defaults.test.d.ts +0 -2
- package/dist/__tests__/seo/settings-defaults.test.d.ts.map +0 -1
- package/dist/__tests__/seo/settings-defaults.test.js +0 -189
- package/dist/__tests__/seo/settings-defaults.test.js.map +0 -1
- package/dist/__tests__/seo/sitemap-notify.test.d.ts +0 -2
- package/dist/__tests__/seo/sitemap-notify.test.d.ts.map +0 -1
- package/dist/__tests__/seo/sitemap-notify.test.js +0 -267
- package/dist/__tests__/seo/sitemap-notify.test.js.map +0 -1
- package/dist/__tests__/seo/sitemap-public.test.d.ts +0 -2
- package/dist/__tests__/seo/sitemap-public.test.d.ts.map +0 -1
- package/dist/__tests__/seo/sitemap-public.test.js +0 -52
- package/dist/__tests__/seo/sitemap-public.test.js.map +0 -1
- package/dist/__tests__/server-site.test.d.ts +0 -2
- package/dist/__tests__/server-site.test.d.ts.map +0 -1
- package/dist/__tests__/server-site.test.js +0 -173
- package/dist/__tests__/server-site.test.js.map +0 -1
- package/dist/__tests__/setup/index.test.d.ts +0 -2
- package/dist/__tests__/setup/index.test.d.ts.map +0 -1
- package/dist/__tests__/setup/index.test.js +0 -128
- package/dist/__tests__/setup/index.test.js.map +0 -1
- package/dist/__tests__/site.test.d.ts +0 -2
- package/dist/__tests__/site.test.d.ts.map +0 -1
- package/dist/__tests__/site.test.js +0 -81
- package/dist/__tests__/site.test.js.map +0 -1
- package/dist/__tests__/storage/auto-wire.test.d.ts +0 -2
- package/dist/__tests__/storage/auto-wire.test.d.ts.map +0 -1
- package/dist/__tests__/storage/auto-wire.test.js +0 -73
- package/dist/__tests__/storage/auto-wire.test.js.map +0 -1
- package/dist/__tests__/upgrade/version-check.test.d.ts +0 -2
- package/dist/__tests__/upgrade/version-check.test.d.ts.map +0 -1
- package/dist/__tests__/upgrade/version-check.test.js +0 -98
- package/dist/__tests__/upgrade/version-check.test.js.map +0 -1
- package/dist/__tests__/validation/publish.test.d.ts +0 -2
- package/dist/__tests__/validation/publish.test.d.ts.map +0 -1
- package/dist/__tests__/validation/publish.test.js +0 -164
- package/dist/__tests__/validation/publish.test.js.map +0 -1
- package/dist/__tests__/webhooks/webhooks.test.d.ts +0 -2
- package/dist/__tests__/webhooks/webhooks.test.d.ts.map +0 -1
- package/dist/__tests__/webhooks/webhooks.test.js +0 -96
- package/dist/__tests__/webhooks/webhooks.test.js.map +0 -1
- package/dist/cache/__tests__/http.test.d.ts +0 -2
- package/dist/cache/__tests__/http.test.d.ts.map +0 -1
- package/dist/cache/__tests__/http.test.js +0 -285
- package/dist/cache/__tests__/http.test.js.map +0 -1
- package/dist/db/__tests__/find-in-batches.test.d.ts +0 -2
- package/dist/db/__tests__/find-in-batches.test.d.ts.map +0 -1
- package/dist/db/__tests__/find-in-batches.test.js +0 -26
- package/dist/db/__tests__/find-in-batches.test.js.map +0 -1
- package/dist/fields/__tests__/presets.test.d.ts +0 -2
- package/dist/fields/__tests__/presets.test.d.ts.map +0 -1
- package/dist/fields/__tests__/presets.test.js +0 -29
- package/dist/fields/__tests__/presets.test.js.map +0 -1
- package/dist/page-builder/__tests__/a11y-fix.test.d.ts +0 -2
- package/dist/page-builder/__tests__/a11y-fix.test.d.ts.map +0 -1
- package/dist/page-builder/__tests__/a11y-fix.test.js +0 -242
- package/dist/page-builder/__tests__/a11y-fix.test.js.map +0 -1
- package/dist/page-builder/__tests__/blocks.test.d.ts +0 -2
- package/dist/page-builder/__tests__/blocks.test.d.ts.map +0 -1
- package/dist/page-builder/__tests__/blocks.test.js +0 -194
- package/dist/page-builder/__tests__/blocks.test.js.map +0 -1
- package/dist/page-builder/__tests__/design-scorer.test.d.ts +0 -2
- package/dist/page-builder/__tests__/design-scorer.test.d.ts.map +0 -1
- package/dist/page-builder/__tests__/design-scorer.test.js +0 -301
- package/dist/page-builder/__tests__/design-scorer.test.js.map +0 -1
- package/dist/page-builder/__tests__/schema.test.d.ts +0 -2
- package/dist/page-builder/__tests__/schema.test.d.ts.map +0 -1
- package/dist/page-builder/__tests__/schema.test.js +0 -191
- package/dist/page-builder/__tests__/schema.test.js.map +0 -1
- package/dist/page-builder/__tests__/seo-analyzer.test.d.ts +0 -2
- package/dist/page-builder/__tests__/seo-analyzer.test.d.ts.map +0 -1
- package/dist/page-builder/__tests__/seo-analyzer.test.js +0 -346
- package/dist/page-builder/__tests__/seo-analyzer.test.js.map +0 -1
- package/dist/page-builder/__tests__/tree.test.d.ts +0 -2
- package/dist/page-builder/__tests__/tree.test.d.ts.map +0 -1
- package/dist/page-builder/__tests__/tree.test.js +0 -257
- package/dist/page-builder/__tests__/tree.test.js.map +0 -1
- package/dist/posts/__tests__/query.test.d.ts +0 -2
- package/dist/posts/__tests__/query.test.d.ts.map +0 -1
- package/dist/posts/__tests__/query.test.js +0 -70
- package/dist/posts/__tests__/query.test.js.map +0 -1
- package/dist/sections/__tests__/bridge.test.d.ts +0 -2
- package/dist/sections/__tests__/bridge.test.d.ts.map +0 -1
- package/dist/sections/__tests__/bridge.test.js +0 -171
- package/dist/sections/__tests__/bridge.test.js.map +0 -1
- package/dist/sections/__tests__/define.test.d.ts +0 -2
- package/dist/sections/__tests__/define.test.d.ts.map +0 -1
- package/dist/sections/__tests__/define.test.js +0 -132
- package/dist/sections/__tests__/define.test.js.map +0 -1
- package/dist/sections/__tests__/embed.test.d.ts +0 -2
- package/dist/sections/__tests__/embed.test.d.ts.map +0 -1
- package/dist/sections/__tests__/embed.test.js +0 -54
- package/dist/sections/__tests__/embed.test.js.map +0 -1
- package/dist/sections/__tests__/media-enrich.test.d.ts +0 -2
- package/dist/sections/__tests__/media-enrich.test.d.ts.map +0 -1
- package/dist/sections/__tests__/media-enrich.test.js +0 -97
- package/dist/sections/__tests__/media-enrich.test.js.map +0 -1
- package/dist/sections/__tests__/sections.test.d.ts +0 -2
- package/dist/sections/__tests__/sections.test.d.ts.map +0 -1
- package/dist/sections/__tests__/sections.test.js +0 -453
- package/dist/sections/__tests__/sections.test.js.map +0 -1
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { handleActuateAPI } from '../../api/index.js';
|
|
3
|
-
import { createSession } from '../../auth/session.js';
|
|
4
|
-
import { setActuateConfig } from '../../config/runtime.js';
|
|
5
|
-
import { initDB } from '../../db.js';
|
|
6
|
-
import { generateToken as generateCsrfToken } from '../../security/csrf.js';
|
|
7
|
-
/**
|
|
8
|
-
* /api/cms/stats must surface "real CMS content" only — never the
|
|
9
|
-
* benchmark suite's `benchmarks` / `bench` collections, never any
|
|
10
|
-
* orphan/test collection sitting in the table.
|
|
11
|
-
*
|
|
12
|
-
* Two consumer shapes are supported and tested here:
|
|
13
|
-
* 1. Production: the consumer registers collections via
|
|
14
|
-
* `handleActuateAPI({ config: { collections: { ... } } })`. The
|
|
15
|
-
* registered slugs become the allowlist; anything else is hidden.
|
|
16
|
-
* 2. Dev: the consumer ships collections only to the admin client
|
|
17
|
-
* (no server-side config). The endpoint falls back to a denylist
|
|
18
|
-
* of internal slugs (`benchmarks`, `bench`).
|
|
19
|
-
*/
|
|
20
|
-
const SECRET = 'test-secret-for-stats-collection-filter-aaaaaaa';
|
|
21
|
-
/**
|
|
22
|
-
* Apply a Prisma-style `where` clause to an in-memory row list.
|
|
23
|
-
* Supports the exact subset our endpoint emits: `deletedAt: null`,
|
|
24
|
-
* `status` equality, and `collection: { in: string[] | notIn: string[] }`.
|
|
25
|
-
*/
|
|
26
|
-
function matchesWhere(row, where) {
|
|
27
|
-
if ('deletedAt' in where && where.deletedAt === null && row.deletedAt != null)
|
|
28
|
-
return false;
|
|
29
|
-
if ('status' in where && typeof where.status === 'string' && row.status !== where.status)
|
|
30
|
-
return false;
|
|
31
|
-
const c = where.collection;
|
|
32
|
-
if (c?.in && !c.in.includes(row.collection))
|
|
33
|
-
return false;
|
|
34
|
-
if (c?.notIn && c.notIn.includes(row.collection))
|
|
35
|
-
return false;
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
function createMockDB(rows) {
|
|
39
|
-
return {
|
|
40
|
-
session: { findUnique: async () => ({ revokedAt: null }) },
|
|
41
|
-
user: { count: async () => rows.length },
|
|
42
|
-
media: { count: async () => 0 },
|
|
43
|
-
formSubmission: { count: async () => 0 },
|
|
44
|
-
webhookEndpoint: { count: async () => 0 },
|
|
45
|
-
document: {
|
|
46
|
-
async count({ where } = {}) {
|
|
47
|
-
return rows.filter((r) => matchesWhere(r, where ?? {})).length;
|
|
48
|
-
},
|
|
49
|
-
async findMany({ where = {}, orderBy: _orderBy, take, select: _select }) {
|
|
50
|
-
const filtered = rows.filter((r) => matchesWhere(r, where));
|
|
51
|
-
filtered.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
|
|
52
|
-
return typeof take === 'number' ? filtered.slice(0, take) : filtered;
|
|
53
|
-
},
|
|
54
|
-
async groupBy({ by, where = {}, _count: _c }) {
|
|
55
|
-
const filtered = rows.filter((r) => matchesWhere(r, where));
|
|
56
|
-
const key = by[0];
|
|
57
|
-
const counts = new Map();
|
|
58
|
-
for (const r of filtered) {
|
|
59
|
-
const k = String(r[key]);
|
|
60
|
-
counts.set(k, (counts.get(k) ?? 0) + 1);
|
|
61
|
-
}
|
|
62
|
-
return Array.from(counts, ([k, count]) => ({ [key]: k, _count: { _all: count } }));
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
async function sessionHeaders(userId = 'user-1') {
|
|
68
|
-
const token = await createSession({ userId, role: 'ADMIN', sessionId: `session-${userId}` }, { secret: SECRET });
|
|
69
|
-
const csrf = await generateCsrfToken();
|
|
70
|
-
return { cookie: `actuate_session=${token}; actuate_csrf=${csrf}` };
|
|
71
|
-
}
|
|
72
|
-
function row(overrides) {
|
|
73
|
-
return {
|
|
74
|
-
id: 'd-' + Math.random().toString(36).slice(2, 8),
|
|
75
|
-
title: 'Untitled',
|
|
76
|
-
status: 'PUBLISHED',
|
|
77
|
-
collection: 'posts',
|
|
78
|
-
updatedAt: new Date(),
|
|
79
|
-
createdById: 'u-1',
|
|
80
|
-
createdBy: { name: 'David', email: 'david@example.com' },
|
|
81
|
-
data: {},
|
|
82
|
-
deletedAt: null,
|
|
83
|
-
...overrides,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
describe('GET /api/cms/stats — collection filter', () => {
|
|
87
|
-
const originalSecret = process.env.CMS_SECRET;
|
|
88
|
-
beforeEach(() => {
|
|
89
|
-
process.env.CMS_SECRET = SECRET;
|
|
90
|
-
});
|
|
91
|
-
afterEach(() => {
|
|
92
|
-
if (originalSecret === undefined)
|
|
93
|
-
delete process.env.CMS_SECRET;
|
|
94
|
-
else
|
|
95
|
-
process.env.CMS_SECRET = originalSecret;
|
|
96
|
-
delete globalThis.__actuateConfig;
|
|
97
|
-
});
|
|
98
|
-
it('uses registered collections as an allowlist when config.collections is populated', async () => {
|
|
99
|
-
const docs = [
|
|
100
|
-
row({ id: 'p1', collection: 'posts', title: 'Real Post' }),
|
|
101
|
-
row({ id: 'pg1', collection: 'pages', title: 'Real Page' }),
|
|
102
|
-
// Benchmark docs sitting alongside in the same table:
|
|
103
|
-
row({ id: 'b1', collection: 'benchmarks', title: 'Bench A' }),
|
|
104
|
-
row({ id: 'b2', collection: 'bench', title: 'Bench B' }),
|
|
105
|
-
// An orphan collection from a removed feature:
|
|
106
|
-
row({ id: 'o1', collection: 'old_removed', title: 'Orphan' }),
|
|
107
|
-
];
|
|
108
|
-
const db = createMockDB(docs);
|
|
109
|
-
initDB(db);
|
|
110
|
-
const handler = handleActuateAPI({
|
|
111
|
-
prismaClient: db,
|
|
112
|
-
config: {
|
|
113
|
-
collections: {
|
|
114
|
-
posts: { slug: 'posts', fields: {} },
|
|
115
|
-
pages: { slug: 'pages', fields: {} },
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
const headers = await sessionHeaders();
|
|
120
|
-
const res = await handler(new Request('https://example.com/api/cms/stats', { headers: { cookie: headers.cookie } }));
|
|
121
|
-
expect(res.status).toBe(200);
|
|
122
|
-
const body = (await res.json());
|
|
123
|
-
expect(body.data.totalDocuments).toBe(2); // posts + pages only
|
|
124
|
-
expect(body.data.collectionCounts).toEqual({ posts: 1, pages: 1 });
|
|
125
|
-
const recentIds = body.data.recentDocuments.map((d) => d.id).sort();
|
|
126
|
-
expect(recentIds).toEqual(['p1', 'pg1']);
|
|
127
|
-
// Belt and suspenders:
|
|
128
|
-
const collections = new Set(body.data.recentDocuments.map((d) => d.collection));
|
|
129
|
-
expect(collections.has('benchmarks')).toBe(false);
|
|
130
|
-
expect(collections.has('bench')).toBe(false);
|
|
131
|
-
expect(collections.has('old_removed')).toBe(false);
|
|
132
|
-
});
|
|
133
|
-
it('falls back to the internal denylist when config.collections is empty', async () => {
|
|
134
|
-
// Dev-style setup: handler is created without `config.collections`,
|
|
135
|
-
// simulating the apps/dev pattern where collections live on the
|
|
136
|
-
// admin client only.
|
|
137
|
-
const docs = [
|
|
138
|
-
row({ id: 'p1', collection: 'posts', title: 'Real Post' }),
|
|
139
|
-
row({ id: 'pg1', collection: 'pages', title: 'Real Page' }),
|
|
140
|
-
row({ id: 'b1', collection: 'benchmarks', title: 'Bench A' }),
|
|
141
|
-
row({ id: 'b2', collection: 'bench', title: 'Bench B' }),
|
|
142
|
-
row({ id: 'o1', collection: 'old_removed', title: 'Orphan' }),
|
|
143
|
-
];
|
|
144
|
-
const db = createMockDB(docs);
|
|
145
|
-
initDB(db);
|
|
146
|
-
setActuateConfig({});
|
|
147
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
148
|
-
const headers = await sessionHeaders();
|
|
149
|
-
const res = await handler(new Request('https://example.com/api/cms/stats', { headers: { cookie: headers.cookie } }));
|
|
150
|
-
expect(res.status).toBe(200);
|
|
151
|
-
const body = (await res.json());
|
|
152
|
-
// Anything NOT in the denylist counts as content — including the
|
|
153
|
-
// legacy `old_removed` rows. That's the right trade-off for the
|
|
154
|
-
// dev fallback: better to over-show than to hide live editor
|
|
155
|
-
// collections we don't know about.
|
|
156
|
-
const recentCollections = body.data.recentDocuments.map((d) => d.collection);
|
|
157
|
-
expect(recentCollections).toContain('posts');
|
|
158
|
-
expect(recentCollections).toContain('pages');
|
|
159
|
-
expect(recentCollections).toContain('old_removed');
|
|
160
|
-
expect(recentCollections).not.toContain('benchmarks');
|
|
161
|
-
expect(recentCollections).not.toContain('bench');
|
|
162
|
-
expect(body.data.collectionCounts.benchmarks).toBeUndefined();
|
|
163
|
-
expect(body.data.collectionCounts.bench).toBeUndefined();
|
|
164
|
-
expect(body.data.collectionCounts.posts).toBe(1);
|
|
165
|
-
});
|
|
166
|
-
it('still respects deletedAt: null alongside the collection filter', async () => {
|
|
167
|
-
const docs = [
|
|
168
|
-
row({ id: 'p1', collection: 'posts', title: 'Live' }),
|
|
169
|
-
row({
|
|
170
|
-
id: 'p2',
|
|
171
|
-
collection: 'posts',
|
|
172
|
-
title: 'Trashed',
|
|
173
|
-
deletedAt: new Date('2026-01-01'),
|
|
174
|
-
}),
|
|
175
|
-
];
|
|
176
|
-
const db = createMockDB(docs);
|
|
177
|
-
initDB(db);
|
|
178
|
-
const handler = handleActuateAPI({
|
|
179
|
-
prismaClient: db,
|
|
180
|
-
config: { collections: { posts: { slug: 'posts', fields: {} } } },
|
|
181
|
-
});
|
|
182
|
-
const headers = await sessionHeaders();
|
|
183
|
-
const res = await handler(new Request('https://example.com/api/cms/stats', { headers: { cookie: headers.cookie } }));
|
|
184
|
-
const body = (await res.json());
|
|
185
|
-
expect(body.data.totalDocuments).toBe(1);
|
|
186
|
-
expect(body.data.recentDocuments).toHaveLength(1);
|
|
187
|
-
expect(body.data.recentDocuments[0].id).toBe('p1');
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
//# sourceMappingURL=stats-collection-filter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stats-collection-filter.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/stats-collection-filter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stats-routes.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/api/stats-routes.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { handleActuateAPI } from '../../api/index.js';
|
|
3
|
-
import { createSession } from '../../auth/session.js';
|
|
4
|
-
import { initDB } from '../../db.js';
|
|
5
|
-
import { generateToken as generateCsrfToken } from '../../security/csrf.js';
|
|
6
|
-
/**
|
|
7
|
-
* Integration tests for the dashboard stats endpoints introduced for
|
|
8
|
-
* the "Delivery API" and "Content Health" cards on the dashboard.
|
|
9
|
-
*
|
|
10
|
-
* These tests lock down the JSON response shape the dashboard depends
|
|
11
|
-
* on so a future refactor can't silently regress the client. They use
|
|
12
|
-
* the same mock-DB pattern as `notifications-routes.test.ts`.
|
|
13
|
-
*/
|
|
14
|
-
const SECRET = 'test-secret-for-stats-routes-aaaaaaaaaaaaaaaaaa';
|
|
15
|
-
function createMockDB(args = {}) {
|
|
16
|
-
const metrics = args.metrics ?? [];
|
|
17
|
-
const issues = args.issues ?? [];
|
|
18
|
-
return {
|
|
19
|
-
session: { findUnique: async () => ({ revokedAt: null }) },
|
|
20
|
-
user: {},
|
|
21
|
-
apiRequestMetric: {
|
|
22
|
-
async findMany({ where, select: _select, }) {
|
|
23
|
-
return metrics.filter((m) => {
|
|
24
|
-
if (m.bucketStart < where.bucketStart.gte)
|
|
25
|
-
return false;
|
|
26
|
-
if (where.bucketStart.lt && m.bucketStart >= where.bucketStart.lt)
|
|
27
|
-
return false;
|
|
28
|
-
return true;
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
webhookEndpoint: {
|
|
33
|
-
async count({ where } = {}) {
|
|
34
|
-
if (where?.active === true)
|
|
35
|
-
return 2;
|
|
36
|
-
return 3;
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
contentIssue: {
|
|
40
|
-
async groupBy({ by, _sum }) {
|
|
41
|
-
void by;
|
|
42
|
-
void _sum;
|
|
43
|
-
const grouped = new Map();
|
|
44
|
-
for (const i of issues)
|
|
45
|
-
grouped.set(i.type, (grouped.get(i.type) ?? 0) + i.count);
|
|
46
|
-
return Array.from(grouped, ([type, count]) => ({ type, _sum: { count } }));
|
|
47
|
-
},
|
|
48
|
-
async findFirst({ orderBy: _orderBy, select: _select }) {
|
|
49
|
-
if (issues.length === 0)
|
|
50
|
-
return null;
|
|
51
|
-
const latest = issues.reduce((a, b) => (a.lastSeenAt > b.lastSeenAt ? a : b));
|
|
52
|
-
return { lastSeenAt: latest.lastSeenAt };
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
async function sessionHeaders(userId = 'user-1') {
|
|
58
|
-
const token = await createSession({ userId, role: 'ADMIN', sessionId: `session-${userId}` }, { secret: SECRET });
|
|
59
|
-
const csrf = await generateCsrfToken();
|
|
60
|
-
return {
|
|
61
|
-
cookie: `actuate_session=${token}; actuate_csrf=${csrf}`,
|
|
62
|
-
'x-csrf-token': csrf,
|
|
63
|
-
'content-type': 'application/json',
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
describe('GET /api/cms/stats/api-delivery', () => {
|
|
67
|
-
const originalSecret = process.env.CMS_SECRET;
|
|
68
|
-
beforeEach(() => {
|
|
69
|
-
process.env.CMS_SECRET = SECRET;
|
|
70
|
-
});
|
|
71
|
-
afterEach(() => {
|
|
72
|
-
if (originalSecret === undefined)
|
|
73
|
-
delete process.env.CMS_SECRET;
|
|
74
|
-
else
|
|
75
|
-
process.env.CMS_SECRET = originalSecret;
|
|
76
|
-
});
|
|
77
|
-
it('rejects unauthenticated requests with 401', async () => {
|
|
78
|
-
const db = createMockDB();
|
|
79
|
-
initDB(db);
|
|
80
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
81
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/api-delivery'));
|
|
82
|
-
expect(res.status).toBe(401);
|
|
83
|
-
});
|
|
84
|
-
it('returns the empty payload (hasData=false) when no metrics exist', async () => {
|
|
85
|
-
const db = createMockDB();
|
|
86
|
-
initDB(db);
|
|
87
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
88
|
-
const headers = await sessionHeaders();
|
|
89
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/api-delivery', {
|
|
90
|
-
headers: { cookie: headers.cookie },
|
|
91
|
-
}));
|
|
92
|
-
expect(res.status).toBe(200);
|
|
93
|
-
const body = (await res.json());
|
|
94
|
-
expect(body.data).toMatchObject({
|
|
95
|
-
hasData: false,
|
|
96
|
-
requests24h: 0,
|
|
97
|
-
requestsPrev24h: 0,
|
|
98
|
-
deltaPercent: null,
|
|
99
|
-
errorRate: 0,
|
|
100
|
-
avgLatencyMs: 0,
|
|
101
|
-
p95LatencyMs: 0,
|
|
102
|
-
});
|
|
103
|
-
// Webhook counters still come from the mocked WebhookEndpoint table.
|
|
104
|
-
expect(body.data.webhookCount).toBe(3);
|
|
105
|
-
expect(body.data.webhookActiveCount).toBe(2);
|
|
106
|
-
});
|
|
107
|
-
it('aggregates 24h request volume, error rate, and avg latency', async () => {
|
|
108
|
-
// Two buckets:
|
|
109
|
-
// - 100 2xx requests, sumLatency 5000 (avg 50ms)
|
|
110
|
-
// - 10 5xx requests, sumLatency 1000 (avg 100ms)
|
|
111
|
-
// Total: 110 requests, 10 errors → 9.09% error rate. Avg latency
|
|
112
|
-
// = 6000 / 110 ≈ 54.5ms.
|
|
113
|
-
const now = new Date();
|
|
114
|
-
const bucketTime = new Date(now.getTime() - 60_000);
|
|
115
|
-
const hist2xx = new Array(12).fill(0);
|
|
116
|
-
hist2xx[6] = 100; // 32-64ms bucket
|
|
117
|
-
const hist5xx = new Array(12).fill(0);
|
|
118
|
-
hist5xx[7] = 10; // 64-128ms bucket
|
|
119
|
-
const db = createMockDB({
|
|
120
|
-
metrics: [
|
|
121
|
-
{
|
|
122
|
-
statusBucket: '2xx',
|
|
123
|
-
count: 100,
|
|
124
|
-
sumLatencyMs: 5000,
|
|
125
|
-
maxLatencyMs: 60,
|
|
126
|
-
latencyHistogram: hist2xx,
|
|
127
|
-
bucketStart: bucketTime,
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
statusBucket: '5xx',
|
|
131
|
-
count: 10,
|
|
132
|
-
sumLatencyMs: 1000,
|
|
133
|
-
maxLatencyMs: 110,
|
|
134
|
-
latencyHistogram: hist5xx,
|
|
135
|
-
bucketStart: bucketTime,
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
});
|
|
139
|
-
initDB(db);
|
|
140
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
141
|
-
const headers = await sessionHeaders();
|
|
142
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/api-delivery', {
|
|
143
|
-
headers: { cookie: headers.cookie },
|
|
144
|
-
}));
|
|
145
|
-
expect(res.status).toBe(200);
|
|
146
|
-
const body = (await res.json());
|
|
147
|
-
expect(body.data.hasData).toBe(true);
|
|
148
|
-
expect(body.data.requests24h).toBe(110);
|
|
149
|
-
expect(body.data.errorRate).toBeCloseTo(0.0909, 3);
|
|
150
|
-
expect(body.data.avgLatencyMs).toBeCloseTo(54.5, 1);
|
|
151
|
-
// p95 of 100×bucket6 + 10×bucket7 = watermark at 104.5; cumulative
|
|
152
|
-
// hits 110 in bucket 7 → upper bound 128.
|
|
153
|
-
expect(body.data.p95LatencyMs).toBe(128);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
describe('GET /api/cms/stats/content-health', () => {
|
|
157
|
-
const originalSecret = process.env.CMS_SECRET;
|
|
158
|
-
beforeEach(() => {
|
|
159
|
-
process.env.CMS_SECRET = SECRET;
|
|
160
|
-
});
|
|
161
|
-
afterEach(() => {
|
|
162
|
-
if (originalSecret === undefined)
|
|
163
|
-
delete process.env.CMS_SECRET;
|
|
164
|
-
else
|
|
165
|
-
process.env.CMS_SECRET = originalSecret;
|
|
166
|
-
});
|
|
167
|
-
it('rejects unauthenticated requests with 401', async () => {
|
|
168
|
-
const db = createMockDB();
|
|
169
|
-
initDB(db);
|
|
170
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
171
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/content-health'));
|
|
172
|
-
expect(res.status).toBe(401);
|
|
173
|
-
});
|
|
174
|
-
it('returns a perfect score (100, "Good") and zero counts when no issues exist', async () => {
|
|
175
|
-
const db = createMockDB();
|
|
176
|
-
initDB(db);
|
|
177
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
178
|
-
const headers = await sessionHeaders();
|
|
179
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/content-health', {
|
|
180
|
-
headers: { cookie: headers.cookie },
|
|
181
|
-
}));
|
|
182
|
-
expect(res.status).toBe(200);
|
|
183
|
-
const body = (await res.json());
|
|
184
|
-
expect(body.data.score).toBe(100);
|
|
185
|
-
expect(body.data.label).toBe('Good');
|
|
186
|
-
expect(body.data.totalIssues).toBe(0);
|
|
187
|
-
expect(body.data.lastScanAt).toBeNull();
|
|
188
|
-
expect(body.data.counts).toEqual({
|
|
189
|
-
MISSING_META_DESCRIPTION: 0,
|
|
190
|
-
MISSING_ALT_TEXT: 0,
|
|
191
|
-
BROKEN_INTERNAL_LINK: 0,
|
|
192
|
-
OUTDATED_CONTENT: 0,
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
it('aggregates counts and computes a penalty-weighted score', async () => {
|
|
196
|
-
// 5 missing meta (5×5=25 penalty)
|
|
197
|
-
// 12 missing alt (12×2=24 penalty)
|
|
198
|
-
// 2 broken links (2×10=20 penalty)
|
|
199
|
-
// 8 outdated (8×3=24 penalty)
|
|
200
|
-
// → score = 100 - 93 = 7
|
|
201
|
-
const db = createMockDB({
|
|
202
|
-
issues: [
|
|
203
|
-
{
|
|
204
|
-
type: 'MISSING_META_DESCRIPTION',
|
|
205
|
-
count: 5,
|
|
206
|
-
lastSeenAt: new Date('2026-05-28T00:00:00Z'),
|
|
207
|
-
},
|
|
208
|
-
{ type: 'MISSING_ALT_TEXT', count: 12, lastSeenAt: new Date('2026-05-28T01:00:00Z') },
|
|
209
|
-
{ type: 'BROKEN_INTERNAL_LINK', count: 2, lastSeenAt: new Date('2026-05-28T02:00:00Z') },
|
|
210
|
-
{ type: 'OUTDATED_CONTENT', count: 8, lastSeenAt: new Date('2026-05-28T03:00:00Z') },
|
|
211
|
-
],
|
|
212
|
-
});
|
|
213
|
-
initDB(db);
|
|
214
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
215
|
-
const headers = await sessionHeaders();
|
|
216
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/content-health', {
|
|
217
|
-
headers: { cookie: headers.cookie },
|
|
218
|
-
}));
|
|
219
|
-
expect(res.status).toBe(200);
|
|
220
|
-
const body = (await res.json());
|
|
221
|
-
expect(body.data.totalIssues).toBe(27);
|
|
222
|
-
expect(body.data.score).toBe(7);
|
|
223
|
-
expect(body.data.label).toBe('Poor');
|
|
224
|
-
expect(body.data.counts.MISSING_META_DESCRIPTION).toBe(5);
|
|
225
|
-
expect(body.data.counts.MISSING_ALT_TEXT).toBe(12);
|
|
226
|
-
expect(body.data.counts.BROKEN_INTERNAL_LINK).toBe(2);
|
|
227
|
-
expect(body.data.counts.OUTDATED_CONTENT).toBe(8);
|
|
228
|
-
expect(body.data.lastScanAt).toBe('2026-05-28T03:00:00.000Z');
|
|
229
|
-
});
|
|
230
|
-
it('floors the score at 0 when penalties exceed 100', async () => {
|
|
231
|
-
const db = createMockDB({
|
|
232
|
-
issues: [
|
|
233
|
-
{
|
|
234
|
-
type: 'BROKEN_INTERNAL_LINK',
|
|
235
|
-
count: 50, // 500 penalty
|
|
236
|
-
lastSeenAt: new Date(),
|
|
237
|
-
},
|
|
238
|
-
],
|
|
239
|
-
});
|
|
240
|
-
initDB(db);
|
|
241
|
-
const handler = handleActuateAPI({ prismaClient: db });
|
|
242
|
-
const headers = await sessionHeaders();
|
|
243
|
-
const res = await handler(new Request('https://example.com/api/cms/stats/content-health', {
|
|
244
|
-
headers: { cookie: headers.cookie },
|
|
245
|
-
}));
|
|
246
|
-
const body = (await res.json());
|
|
247
|
-
expect(body.data.score).toBe(0);
|
|
248
|
-
expect(body.data.label).toBe('Poor');
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
//# sourceMappingURL=stats-routes.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stats-routes.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/stats-routes.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stats-seo-cache.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/api/stats-seo-cache.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { handleActuateAPI } from '../../api/index.js';
|
|
3
|
-
import { __resetDashboardSeoCache } from '../../api/routes/dashboard.js';
|
|
4
|
-
import { createSession } from '../../auth/session.js';
|
|
5
|
-
import { initDB } from '../../db.js';
|
|
6
|
-
import { generateToken as generateCsrfToken } from '../../security/csrf.js';
|
|
7
|
-
/**
|
|
8
|
-
* `/stats` caches its average-SEO-score computation (a read + scan over
|
|
9
|
-
* up to 200 documents) per content-scope for a short TTL. These tests
|
|
10
|
-
* assert the cache is actually consulted: a second request within the
|
|
11
|
-
* window must NOT re-issue the 200-document SEO read, and clearing the
|
|
12
|
-
* cache forces a recompute.
|
|
13
|
-
*/
|
|
14
|
-
const SECRET = 'test-secret-for-stats-seo-cache-aaaaaaaaaaaaaaaa';
|
|
15
|
-
function createMockDB(rows) {
|
|
16
|
-
let seoReadCount = 0;
|
|
17
|
-
const allRows = rows.map((r, i) => ({
|
|
18
|
-
id: `d${i}`,
|
|
19
|
-
title: `Doc ${i}`,
|
|
20
|
-
status: 'PUBLISHED',
|
|
21
|
-
collection: 'posts',
|
|
22
|
-
updatedAt: new Date(),
|
|
23
|
-
createdById: 'u1',
|
|
24
|
-
createdBy: { name: 'Author', email: 'a@example.com' },
|
|
25
|
-
data: r.data,
|
|
26
|
-
}));
|
|
27
|
-
const db = {
|
|
28
|
-
session: { findUnique: async () => ({ revokedAt: null }) },
|
|
29
|
-
user: { count: async () => 0 },
|
|
30
|
-
media: { count: async () => 0 },
|
|
31
|
-
formSubmission: { count: async () => 0 },
|
|
32
|
-
webhookEndpoint: { count: async () => 0 },
|
|
33
|
-
document: {
|
|
34
|
-
count: async () => allRows.length,
|
|
35
|
-
// The SEO read is the only `findMany` with `take: 200` + `select.data`.
|
|
36
|
-
findMany: async ({ take, select }) => {
|
|
37
|
-
if (take === 200 && select?.data)
|
|
38
|
-
seoReadCount++;
|
|
39
|
-
return allRows;
|
|
40
|
-
},
|
|
41
|
-
groupBy: async () => [],
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
return { db, getSeoReadCount: () => seoReadCount };
|
|
45
|
-
}
|
|
46
|
-
async function sessionCookie() {
|
|
47
|
-
const token = await createSession({ userId: 'user-1', role: 'ADMIN', sessionId: 'session-1' }, { secret: SECRET });
|
|
48
|
-
const csrf = await generateCsrfToken();
|
|
49
|
-
return `actuate_session=${token}; actuate_csrf=${csrf}`;
|
|
50
|
-
}
|
|
51
|
-
const POSTS_CONFIG = { collections: { posts: { slug: 'posts', fields: {} } } };
|
|
52
|
-
describe('GET /api/cms/stats — SEO score cache', () => {
|
|
53
|
-
const originalSecret = process.env.CMS_SECRET;
|
|
54
|
-
beforeEach(() => {
|
|
55
|
-
process.env.CMS_SECRET = SECRET;
|
|
56
|
-
__resetDashboardSeoCache();
|
|
57
|
-
});
|
|
58
|
-
afterEach(() => {
|
|
59
|
-
if (originalSecret === undefined)
|
|
60
|
-
delete process.env.CMS_SECRET;
|
|
61
|
-
else
|
|
62
|
-
process.env.CMS_SECRET = originalSecret;
|
|
63
|
-
delete globalThis.__actuateConfig;
|
|
64
|
-
__resetDashboardSeoCache();
|
|
65
|
-
});
|
|
66
|
-
it('computes the score once and serves repeat requests from cache', async () => {
|
|
67
|
-
const { db, getSeoReadCount } = createMockDB([
|
|
68
|
-
{ data: { seoTitle: 'a', metaDescription: 'b' } }, // 50
|
|
69
|
-
{ data: { seoTitle: 'a', metaDescription: 'b', canonical: 'c', schemaType: 'Article' } }, // 100
|
|
70
|
-
]);
|
|
71
|
-
initDB(db);
|
|
72
|
-
const handler = handleActuateAPI({ prismaClient: db, config: POSTS_CONFIG });
|
|
73
|
-
const cookie = await sessionCookie();
|
|
74
|
-
const call = () => handler(new Request('https://example.com/api/cms/stats', { headers: { cookie } }));
|
|
75
|
-
const first = (await (await call()).json());
|
|
76
|
-
expect(first.data.avgSeoScore).toBe(75);
|
|
77
|
-
expect(getSeoReadCount()).toBe(1);
|
|
78
|
-
const second = (await (await call()).json());
|
|
79
|
-
expect(second.data.avgSeoScore).toBe(75);
|
|
80
|
-
// Served from cache — no second 200-document read.
|
|
81
|
-
expect(getSeoReadCount()).toBe(1);
|
|
82
|
-
});
|
|
83
|
-
it('recomputes after the cache is cleared', async () => {
|
|
84
|
-
const { db, getSeoReadCount } = createMockDB([{ data: { seoTitle: 'a' } }]); // 25
|
|
85
|
-
initDB(db);
|
|
86
|
-
const handler = handleActuateAPI({ prismaClient: db, config: POSTS_CONFIG });
|
|
87
|
-
const cookie = await sessionCookie();
|
|
88
|
-
const call = () => handler(new Request('https://example.com/api/cms/stats', { headers: { cookie } }));
|
|
89
|
-
await call();
|
|
90
|
-
expect(getSeoReadCount()).toBe(1);
|
|
91
|
-
__resetDashboardSeoCache();
|
|
92
|
-
await call();
|
|
93
|
-
expect(getSeoReadCount()).toBe(2);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
//# sourceMappingURL=stats-seo-cache.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stats-seo-cache.test.js","sourceRoot":"","sources":["../../../src/__tests__/api/stats-seo-cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"totp-login.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/api/totp-login.test.ts"],"names":[],"mappings":""}
|