@actuate-media/cms-core 0.83.0 → 0.84.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 +12 -0
- 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/next-site.d.ts +28 -0
- package/dist/next-site.d.ts.map +1 -0
- package/dist/next-site.js +58 -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/package.json +21 -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,75 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { sanitizeHtml, stripHtml } from '../../security/sanitize.js';
|
|
3
|
-
describe('sanitizeHtml', () => {
|
|
4
|
-
it('strips script tags', () => {
|
|
5
|
-
const input = '<p>Hello</p><script>alert("xss")</script>';
|
|
6
|
-
const result = sanitizeHtml(input);
|
|
7
|
-
expect(result).not.toContain('<script');
|
|
8
|
-
expect(result).toContain('<p>Hello</p>');
|
|
9
|
-
});
|
|
10
|
-
it('strips onerror attributes', () => {
|
|
11
|
-
const input = '<img src="x" onerror="alert(1)" alt="test" />';
|
|
12
|
-
const result = sanitizeHtml(input);
|
|
13
|
-
expect(result).not.toContain('onerror');
|
|
14
|
-
expect(result).toContain('alt="test"');
|
|
15
|
-
});
|
|
16
|
-
it('strips javascript: URLs from hrefs', () => {
|
|
17
|
-
const input = '<a href="javascript:alert(1)">click</a>';
|
|
18
|
-
const result = sanitizeHtml(input);
|
|
19
|
-
expect(result).not.toContain('javascript:');
|
|
20
|
-
});
|
|
21
|
-
it('preserves safe HTML', () => {
|
|
22
|
-
const input = '<h1>Title</h1><p>Text with <strong>bold</strong> and <a href="https://example.com">link</a></p>';
|
|
23
|
-
const result = sanitizeHtml(input);
|
|
24
|
-
expect(result).toContain('<h1>');
|
|
25
|
-
expect(result).toContain('<strong>bold</strong>');
|
|
26
|
-
expect(result).toContain('href="https://example.com"');
|
|
27
|
-
});
|
|
28
|
-
it('preserves image tags with allowed attributes', () => {
|
|
29
|
-
const input = '<img src="https://example.com/img.jpg" alt="photo" width="100" />';
|
|
30
|
-
const result = sanitizeHtml(input);
|
|
31
|
-
expect(result).toContain('src="https://example.com/img.jpg"');
|
|
32
|
-
expect(result).toContain('alt="photo"');
|
|
33
|
-
});
|
|
34
|
-
it('preserves tables', () => {
|
|
35
|
-
const input = '<table><thead><tr><th>Header</th></tr></thead><tbody><tr><td>Cell</td></tr></tbody></table>';
|
|
36
|
-
const result = sanitizeHtml(input);
|
|
37
|
-
expect(result).toContain('<table>');
|
|
38
|
-
expect(result).toContain('<th>Header</th>');
|
|
39
|
-
expect(result).toContain('<td>Cell</td>');
|
|
40
|
-
});
|
|
41
|
-
it('strips everything with stripAll option', () => {
|
|
42
|
-
const input = '<p>Hello <strong>world</strong></p>';
|
|
43
|
-
const result = sanitizeHtml(input, { stripAll: true });
|
|
44
|
-
expect(result).toBe('Hello world');
|
|
45
|
-
});
|
|
46
|
-
it('strips style tags', () => {
|
|
47
|
-
const input = '<style>body{display:none}</style><p>visible</p>';
|
|
48
|
-
const result = sanitizeHtml(input);
|
|
49
|
-
expect(result).not.toContain('<style');
|
|
50
|
-
expect(result).toContain('<p>visible</p>');
|
|
51
|
-
});
|
|
52
|
-
it('strips iframe tags', () => {
|
|
53
|
-
const input = '<iframe src="https://evil.com"></iframe><p>safe</p>';
|
|
54
|
-
const result = sanitizeHtml(input);
|
|
55
|
-
expect(result).not.toContain('<iframe');
|
|
56
|
-
expect(result).toContain('<p>safe</p>');
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
describe('stripHtml', () => {
|
|
60
|
-
it('returns plain text from HTML', () => {
|
|
61
|
-
const input = '<p>Hello <strong>world</strong></p>';
|
|
62
|
-
expect(stripHtml(input)).toBe('Hello world');
|
|
63
|
-
});
|
|
64
|
-
it('handles empty string', () => {
|
|
65
|
-
expect(stripHtml('')).toBe('');
|
|
66
|
-
});
|
|
67
|
-
it('strips nested tags', () => {
|
|
68
|
-
const input = '<div><ul><li>Item 1</li><li>Item 2</li></ul></div>';
|
|
69
|
-
const result = stripHtml(input);
|
|
70
|
-
expect(result).toContain('Item 1');
|
|
71
|
-
expect(result).toContain('Item 2');
|
|
72
|
-
expect(result).not.toContain('<');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
//# sourceMappingURL=sanitize.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/sanitize.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"secret-storage.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/secret-storage.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { encryptSecret, decryptSecret, isEncrypted, encryptStringArray, decryptStringArray, } from '../../security/secret-storage.js';
|
|
3
|
-
const KEY = 'a'.repeat(64); // 32 bytes hex
|
|
4
|
-
describe('secret-storage', () => {
|
|
5
|
-
it('round-trips a secret when CMS_ENCRYPTION_KEY is set', async () => {
|
|
6
|
-
process.env.CMS_ENCRYPTION_KEY = KEY;
|
|
7
|
-
const ciphertext = await encryptSecret('totp-seed-12345');
|
|
8
|
-
expect(ciphertext.startsWith('enc:v1:')).toBe(true);
|
|
9
|
-
expect(isEncrypted(ciphertext)).toBe(true);
|
|
10
|
-
expect(await decryptSecret(ciphertext)).toBe('totp-seed-12345');
|
|
11
|
-
});
|
|
12
|
-
it('passes plaintext through unchanged when CMS_ENCRYPTION_KEY is unset', async () => {
|
|
13
|
-
delete process.env.CMS_ENCRYPTION_KEY;
|
|
14
|
-
const out = await encryptSecret('plain-secret');
|
|
15
|
-
expect(out).toBe('plain-secret');
|
|
16
|
-
expect(isEncrypted(out)).toBe(false);
|
|
17
|
-
// Reads of plaintext values that were never encrypted return as-is.
|
|
18
|
-
expect(await decryptSecret('plain-secret')).toBe('plain-secret');
|
|
19
|
-
});
|
|
20
|
-
it('encryptStringArray + decryptStringArray round-trip', async () => {
|
|
21
|
-
process.env.CMS_ENCRYPTION_KEY = KEY;
|
|
22
|
-
const codes = ['abc-123', 'def-456', 'ghi-789'];
|
|
23
|
-
const enc = await encryptStringArray(codes);
|
|
24
|
-
expect(enc.every(isEncrypted)).toBe(true);
|
|
25
|
-
expect(await decryptStringArray(enc)).toEqual(codes);
|
|
26
|
-
});
|
|
27
|
-
it('decryptSecret refuses encrypted values without a key', async () => {
|
|
28
|
-
process.env.CMS_ENCRYPTION_KEY = KEY;
|
|
29
|
-
const ciphertext = await encryptSecret('shh');
|
|
30
|
-
delete process.env.CMS_ENCRYPTION_KEY;
|
|
31
|
-
await expect(decryptSecret(ciphertext)).rejects.toThrow(/CMS_ENCRYPTION_KEY/);
|
|
32
|
-
});
|
|
33
|
-
it('round-trip data is non-deterministic (random IV)', async () => {
|
|
34
|
-
process.env.CMS_ENCRYPTION_KEY = KEY;
|
|
35
|
-
const a = await encryptSecret('same');
|
|
36
|
-
const b = await encryptSecret('same');
|
|
37
|
-
expect(a).not.toBe(b);
|
|
38
|
-
expect(await decryptSecret(a)).toBe('same');
|
|
39
|
-
expect(await decryptSecret(b)).toBe('same');
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
//# sourceMappingURL=secret-storage.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"secret-storage.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/secret-storage.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/ssrf.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { canonicalizeHostname, isPrivateAddress } from '../../security/ip-canon.js';
|
|
3
|
-
import { resolveAndCheck, validateWebhookUrl } from '../../security/webhook.js';
|
|
4
|
-
describe('canonicalizeHostname — IPv4 encodings', () => {
|
|
5
|
-
it.each([
|
|
6
|
-
['127.0.0.1', '127.0.0.1'],
|
|
7
|
-
['10.0.0.1', '10.0.0.1'],
|
|
8
|
-
['192.168.1.1', '192.168.1.1'],
|
|
9
|
-
// Decimal: 127*2^24 = 2130706432 → 127.0.0.0; +1 = 127.0.0.1
|
|
10
|
-
['2130706433', '127.0.0.1'],
|
|
11
|
-
// Octal (0177 = 127, 0 = 0, 0 = 0, 01 = 1)
|
|
12
|
-
['0177.0.0.1', '127.0.0.1'],
|
|
13
|
-
['0177.0.0.01', '127.0.0.1'],
|
|
14
|
-
// Hex
|
|
15
|
-
['0x7f.0.0.1', '127.0.0.1'],
|
|
16
|
-
['0x7f000001', '127.0.0.1'],
|
|
17
|
-
// Short forms
|
|
18
|
-
['127.1', '127.0.0.1'],
|
|
19
|
-
['10.1', '10.0.0.1'],
|
|
20
|
-
['127.0.1', '127.0.0.1'],
|
|
21
|
-
])('canonicalizes %s → %s', (input, expected) => {
|
|
22
|
-
const c = canonicalizeHostname(input);
|
|
23
|
-
expect(c.isHostname).toBe(false);
|
|
24
|
-
expect(c.ipv4).toBe(expected);
|
|
25
|
-
});
|
|
26
|
-
it('rejects malformed IPv4 (out-of-range octet)', () => {
|
|
27
|
-
const c = canonicalizeHostname('256.0.0.1');
|
|
28
|
-
expect(c.isHostname).toBe(true); // falls through to "treat as hostname"
|
|
29
|
-
});
|
|
30
|
-
it('rejects malformed octal (digit 8 is invalid)', () => {
|
|
31
|
-
const c = canonicalizeHostname('0888.0.0.1');
|
|
32
|
-
expect(c.isHostname).toBe(true);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
describe('canonicalizeHostname — IPv6 encodings', () => {
|
|
36
|
-
it.each([
|
|
37
|
-
['::1', '::ffff:127.0.0.1 OR plain'], // checked separately below
|
|
38
|
-
])('detects IPv6 forms', () => {
|
|
39
|
-
expect(canonicalizeHostname('::1').isHostname).toBe(false);
|
|
40
|
-
});
|
|
41
|
-
it('canonicalizes ::ffff:127.0.0.1 to underlying IPv4', () => {
|
|
42
|
-
const c = canonicalizeHostname('::ffff:127.0.0.1');
|
|
43
|
-
expect(c.ipv4).toBe('127.0.0.1');
|
|
44
|
-
});
|
|
45
|
-
it('canonicalizes ::ffff:7f00:1 (hex form) to underlying IPv4', () => {
|
|
46
|
-
const c = canonicalizeHostname('::ffff:7f00:1');
|
|
47
|
-
expect(c.ipv4).toBe('127.0.0.1');
|
|
48
|
-
});
|
|
49
|
-
it('canonicalizes ::127.0.0.1 (deprecated IPv4-compatible) to underlying IPv4', () => {
|
|
50
|
-
const c = canonicalizeHostname('::127.0.0.1');
|
|
51
|
-
expect(c.ipv4).toBe('127.0.0.1');
|
|
52
|
-
});
|
|
53
|
-
it('handles bracketed IPv6 (URL form)', () => {
|
|
54
|
-
const c = canonicalizeHostname('[::1]');
|
|
55
|
-
expect(c.ipv6).toBeDefined();
|
|
56
|
-
});
|
|
57
|
-
it('rejects IPv6 with multiple :: compressions', () => {
|
|
58
|
-
const c = canonicalizeHostname('::1::1');
|
|
59
|
-
expect(c.isHostname).toBe(false);
|
|
60
|
-
expect(c.isValidIp).toBe(false); // <- Bugbot #3: explicit malformed flag
|
|
61
|
-
expect(c.ipv6).toBeUndefined();
|
|
62
|
-
expect(c.ipv4).toBeUndefined();
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
describe('canonicalizeHostname — malformed IP literals', () => {
|
|
66
|
-
// Bugbot review #1/#2/#3 (PR #40): every input that looks like an IP
|
|
67
|
-
// literal but doesn't parse must be flagged with `isValidIp: false` so
|
|
68
|
-
// SSRF gates can fail closed instead of misreading "no IP returned" as
|
|
69
|
-
// "no private IP found".
|
|
70
|
-
it.each([
|
|
71
|
-
'::1::1', // multiple :: compressions
|
|
72
|
-
'::garbage', // non-hex hextet
|
|
73
|
-
'fe80:::1', // triple colon
|
|
74
|
-
'::1:gg::', // bad chars + multiple ::
|
|
75
|
-
'1:2:3:4:5:6:7:8:9', // too many groups
|
|
76
|
-
'abcd::1234::5678', // multiple ::
|
|
77
|
-
])('marks %s as a non-hostname AND non-valid IP', (input) => {
|
|
78
|
-
const c = canonicalizeHostname(input);
|
|
79
|
-
expect(c.isHostname).toBe(false);
|
|
80
|
-
expect(c.isValidIp).toBe(false);
|
|
81
|
-
expect(c.ipv4).toBeUndefined();
|
|
82
|
-
expect(c.ipv6).toBeUndefined();
|
|
83
|
-
});
|
|
84
|
-
it('isPrivateAddress fails closed on the malformed shape', () => {
|
|
85
|
-
// Defense in depth: even if a caller forgets to check `isValidIp`,
|
|
86
|
-
// calling `isPrivateAddress` on a malformed shape returns a non-null
|
|
87
|
-
// reason instead of `null` (which would mean "safe to fetch").
|
|
88
|
-
const c = canonicalizeHostname('::1::1');
|
|
89
|
-
const result = isPrivateAddress(c);
|
|
90
|
-
expect(result).not.toBeNull();
|
|
91
|
-
expect(result?.reason).toMatch(/malformed/i);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
describe('canonicalizeHostname — DNS hostnames pass through', () => {
|
|
95
|
-
it.each(['example.com', 'sub.example.com', 'localhost-but-not-quite.com', 'a-b-c.example'])('leaves %s as a hostname', (input) => {
|
|
96
|
-
const c = canonicalizeHostname(input);
|
|
97
|
-
expect(c.isHostname).toBe(true);
|
|
98
|
-
expect(c.ipv4).toBeUndefined();
|
|
99
|
-
expect(c.ipv6).toBeUndefined();
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
describe('isPrivateAddress', () => {
|
|
103
|
-
it.each([
|
|
104
|
-
'127.0.0.1',
|
|
105
|
-
'10.0.0.1',
|
|
106
|
-
'172.16.0.1',
|
|
107
|
-
'172.31.255.254',
|
|
108
|
-
'192.168.1.1',
|
|
109
|
-
'169.254.169.254', // AWS metadata
|
|
110
|
-
'100.64.0.1', // CGNAT
|
|
111
|
-
'0.0.0.0',
|
|
112
|
-
'198.18.0.1', // benchmark range
|
|
113
|
-
'224.0.0.1', // multicast
|
|
114
|
-
'255.255.255.255', // broadcast
|
|
115
|
-
])('flags %s as private', (ip) => {
|
|
116
|
-
const c = canonicalizeHostname(ip);
|
|
117
|
-
expect(isPrivateAddress(c)).not.toBeNull();
|
|
118
|
-
});
|
|
119
|
-
it.each(['8.8.8.8', '1.1.1.1', '93.184.216.34', '203.0.0.1'])('allows public IP %s', (ip) => {
|
|
120
|
-
const c = canonicalizeHostname(ip);
|
|
121
|
-
expect(isPrivateAddress(c)).toBeNull();
|
|
122
|
-
});
|
|
123
|
-
it.each([
|
|
124
|
-
['::1', '::1 (IPv6 loopback)'],
|
|
125
|
-
['::', ':: (unspecified)'],
|
|
126
|
-
['fe80::1', 'fe80::/10 (IPv6 link-local)'],
|
|
127
|
-
['fc00::1', 'fc00::/7 (IPv6 unique local)'],
|
|
128
|
-
['fd12::1', 'fc00::/7 (IPv6 unique local)'],
|
|
129
|
-
['ff02::1', 'ff00::/8 (IPv6 multicast)'],
|
|
130
|
-
])('flags IPv6 %s as private', (ip) => {
|
|
131
|
-
const c = canonicalizeHostname(ip);
|
|
132
|
-
expect(isPrivateAddress(c)).not.toBeNull();
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
describe('validateWebhookUrl — bypass forms', () => {
|
|
136
|
-
// These are the bypass forms the prior regex-based implementation missed.
|
|
137
|
-
// Each one would have happily POSTed to localhost / metadata IP / RFC1918.
|
|
138
|
-
it.each([
|
|
139
|
-
['decimal IP', 'http://2130706433/'],
|
|
140
|
-
['octal IP', 'http://0177.0.0.1/'],
|
|
141
|
-
['hex IP', 'http://0x7f.0.0.1/'],
|
|
142
|
-
['mixed hex flat', 'http://0x7f000001/'],
|
|
143
|
-
['short form', 'http://127.1/'],
|
|
144
|
-
['IPv4-mapped IPv6', 'http://[::ffff:127.0.0.1]/'],
|
|
145
|
-
['IPv4-compatible IPv6 (deprecated)', 'http://[::127.0.0.1]/'],
|
|
146
|
-
['bracketed IPv6 loopback', 'http://[::1]/'],
|
|
147
|
-
['IPv6 link-local', 'http://[fe80::1]/'],
|
|
148
|
-
['IPv6 unique-local fd00', 'http://[fd00::1]/'],
|
|
149
|
-
['CGNAT range', 'http://100.64.0.1/'],
|
|
150
|
-
['AWS metadata', 'http://169.254.169.254/latest/meta-data/'],
|
|
151
|
-
['benchmark range', 'http://198.18.0.1/'],
|
|
152
|
-
['localhost hostname', 'http://localhost/'],
|
|
153
|
-
['metadata.google.internal', 'http://metadata.google.internal/'],
|
|
154
|
-
['arbitrary .internal hostname', 'http://my-service.internal/'],
|
|
155
|
-
])('rejects %s (%s)', (_label, url) => {
|
|
156
|
-
const result = validateWebhookUrl(url);
|
|
157
|
-
expect(result.valid).toBe(false);
|
|
158
|
-
expect(result.error).toBeDefined();
|
|
159
|
-
});
|
|
160
|
-
it.each([
|
|
161
|
-
['regular https', 'https://example.com/webhook'],
|
|
162
|
-
['public IP literal', 'http://8.8.8.8/'],
|
|
163
|
-
['hostname with port', 'https://api.example.com:8443/hooks/123'],
|
|
164
|
-
])('allows %s (%s)', (_label, url) => {
|
|
165
|
-
const result = validateWebhookUrl(url);
|
|
166
|
-
expect(result.valid).toBe(true);
|
|
167
|
-
});
|
|
168
|
-
it('rejects non-http(s) protocols', () => {
|
|
169
|
-
expect(validateWebhookUrl('file:///etc/passwd').valid).toBe(false);
|
|
170
|
-
expect(validateWebhookUrl('gopher://example.com/').valid).toBe(false);
|
|
171
|
-
expect(validateWebhookUrl('ftp://example.com/').valid).toBe(false);
|
|
172
|
-
expect(validateWebhookUrl('javascript:alert(1)').valid).toBe(false);
|
|
173
|
-
});
|
|
174
|
-
it('rejects malformed URLs', () => {
|
|
175
|
-
expect(validateWebhookUrl('not a url').valid).toBe(false);
|
|
176
|
-
expect(validateWebhookUrl('').valid).toBe(false);
|
|
177
|
-
});
|
|
178
|
-
// Bugbot review #1 (PR #40): malformed IP-shaped hostnames previously
|
|
179
|
-
// slipped through because canonicalizeHostname returned `{isHostname:
|
|
180
|
-
// false}` with no IP fields, and isPrivateAddress returned null —
|
|
181
|
-
// which the validator interpreted as "safe". They must fail closed.
|
|
182
|
-
it.each([
|
|
183
|
-
'http://[::1::1]/', // multi :: IPv6
|
|
184
|
-
'http://[fe80:::1]/', // triple colon
|
|
185
|
-
'http://[abcd::1234::5678]/', // multi ::
|
|
186
|
-
])('rejects malformed IP literal in URL: %s', (url) => {
|
|
187
|
-
const result = validateWebhookUrl(url);
|
|
188
|
-
expect(result.valid).toBe(false);
|
|
189
|
-
expect(result.error).toMatch(/malformed|invalid/i);
|
|
190
|
-
});
|
|
191
|
-
});
|
|
192
|
-
describe('resolveAndCheck — IP literal short-circuit', () => {
|
|
193
|
-
it('rejects malformed IPv6 literal without DNS lookup', async () => {
|
|
194
|
-
// Bugbot review #2 (PR #40): the IP-literal short-circuit path also
|
|
195
|
-
// had the malformed-IP fail-open bug. Verify it now fails closed.
|
|
196
|
-
const result = await resolveAndCheck('::1::1');
|
|
197
|
-
expect(result.safe).toBe(false);
|
|
198
|
-
expect(result.error).toMatch(/malformed/i);
|
|
199
|
-
});
|
|
200
|
-
it('still allows public IP literals', async () => {
|
|
201
|
-
const result = await resolveAndCheck('8.8.8.8');
|
|
202
|
-
expect(result.safe).toBe(true);
|
|
203
|
-
});
|
|
204
|
-
it('still rejects private IP literals', async () => {
|
|
205
|
-
const result = await resolveAndCheck('127.0.0.1');
|
|
206
|
-
expect(result.safe).toBe(false);
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
//# sourceMappingURL=ssrf.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/ssrf.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload-magic.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/upload-magic.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { validateMimeType, checkMagicBytes } from '../../security/upload.js';
|
|
3
|
-
describe('validateMimeType', () => {
|
|
4
|
-
it('accepts an allowlisted type', () => {
|
|
5
|
-
expect(validateMimeType('image/png', ['image/png'])).toBe(true);
|
|
6
|
-
});
|
|
7
|
-
it('rejects a non-allowlisted type', () => {
|
|
8
|
-
expect(validateMimeType('text/html', ['image/png'])).toBe(false);
|
|
9
|
-
});
|
|
10
|
-
it('accepts both Set and Array allowlists', () => {
|
|
11
|
-
expect(validateMimeType('image/jpeg', new Set(['image/jpeg']))).toBe(true);
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
describe('checkMagicBytes', () => {
|
|
15
|
-
function buf(bytes) {
|
|
16
|
-
return new Uint8Array(bytes);
|
|
17
|
-
}
|
|
18
|
-
it('accepts a real PNG header for image/png', () => {
|
|
19
|
-
const png = buf([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0, 0, 0, 0]);
|
|
20
|
-
expect(checkMagicBytes(png, 'image/png').valid).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
it('rejects a JPEG buffer claiming to be PNG', () => {
|
|
23
|
-
const jpeg = buf([0xff, 0xd8, 0xff, 0xe0, 0, 0x10, 0x4a, 0x46, 0x49, 0x46]);
|
|
24
|
-
const result = checkMagicBytes(jpeg, 'image/png');
|
|
25
|
-
expect(result.valid).toBe(false);
|
|
26
|
-
expect(result.detectedMimeType).toBe('image/jpeg');
|
|
27
|
-
});
|
|
28
|
-
it('rejects a WAV file claiming to be WebP (both share the RIFF header)', () => {
|
|
29
|
-
const wav = buf([0x52, 0x49, 0x46, 0x46, 0, 0, 0, 0, 0x57, 0x41, 0x56, 0x45]);
|
|
30
|
-
const result = checkMagicBytes(wav, 'image/webp');
|
|
31
|
-
expect(result.valid).toBe(false);
|
|
32
|
-
expect(result.detectedMimeType).toBe('audio/wav');
|
|
33
|
-
});
|
|
34
|
-
it('accepts a real WebP buffer for image/webp', () => {
|
|
35
|
-
const webp = buf([0x52, 0x49, 0x46, 0x46, 0, 0, 0, 0, 0x57, 0x45, 0x42, 0x50]);
|
|
36
|
-
expect(checkMagicBytes(webp, 'image/webp').valid).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
it('accepts a full GIF89a header but rejects a "GIF" prefix only', () => {
|
|
39
|
-
const valid = buf([0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0, 0, 0, 0]);
|
|
40
|
-
expect(checkMagicBytes(valid, 'image/gif').valid).toBe(true);
|
|
41
|
-
const fake = buf([0x47, 0x49, 0x46, 0x00, 0x00, 0x00, 0, 0, 0, 0]);
|
|
42
|
-
// Without the full signature we can't detect the type, but we also won't lie.
|
|
43
|
-
const result = checkMagicBytes(fake, 'image/gif');
|
|
44
|
-
expect(result.valid).toBe(true); // unknown signature => accept (mime allowlist already gated this)
|
|
45
|
-
});
|
|
46
|
-
it('detects SVG by inspecting XML content', () => {
|
|
47
|
-
const svg = new TextEncoder().encode('<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg"/>');
|
|
48
|
-
expect(checkMagicBytes(svg, 'image/svg+xml').valid).toBe(true);
|
|
49
|
-
});
|
|
50
|
-
it('detects AVIF using the ftyp brand', () => {
|
|
51
|
-
const avif = buf([0, 0, 0, 0x20, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66]);
|
|
52
|
-
expect(checkMagicBytes(avif, 'image/avif').valid).toBe(true);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
//# sourceMappingURL=upload-magic.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload-magic.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/upload-magic.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai-bots.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/seo/ai-bots.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { buildAiBotRobotsLines, detectAiBot, AI_TRAINING_BOTS, AI_RETRIEVAL_BOTS, } from '../../seo/ai-bots.js';
|
|
3
|
-
function uaSet(lines) {
|
|
4
|
-
return new Set(lines.filter((l) => l.startsWith('User-agent: ')).map((l) => l.replace('User-agent: ', '')));
|
|
5
|
-
}
|
|
6
|
-
describe('buildAiBotRobotsLines', () => {
|
|
7
|
-
it('emits nothing when no policy and no legacy flag', () => {
|
|
8
|
-
expect(buildAiBotRobotsLines(undefined, undefined)).toEqual([]);
|
|
9
|
-
expect(buildAiBotRobotsLines({}, false)).toEqual([]);
|
|
10
|
-
});
|
|
11
|
-
it('blocks only training bots when training=block, retrieval=allow', () => {
|
|
12
|
-
const lines = buildAiBotRobotsLines({ training: 'block', retrieval: 'allow' }, undefined);
|
|
13
|
-
const uas = uaSet(lines);
|
|
14
|
-
expect(uas.has('GPTBot')).toBe(true);
|
|
15
|
-
expect(uas.has('CCBot')).toBe(true);
|
|
16
|
-
// Retrieval bots stay allowed (absent from the disallow list).
|
|
17
|
-
expect(uas.has('PerplexityBot')).toBe(false);
|
|
18
|
-
expect(uas.has('OAI-SearchBot')).toBe(false);
|
|
19
|
-
});
|
|
20
|
-
it('blocks only retrieval bots when retrieval=block, training=allow', () => {
|
|
21
|
-
const lines = buildAiBotRobotsLines({ training: 'allow', retrieval: 'block' }, undefined);
|
|
22
|
-
const uas = uaSet(lines);
|
|
23
|
-
expect(uas.has('PerplexityBot')).toBe(true);
|
|
24
|
-
expect(uas.has('ChatGPT-User')).toBe(true);
|
|
25
|
-
expect(uas.has('GPTBot')).toBe(false);
|
|
26
|
-
});
|
|
27
|
-
it('blocks both groups when both are set to block', () => {
|
|
28
|
-
const lines = buildAiBotRobotsLines({ training: 'block', retrieval: 'block' }, undefined);
|
|
29
|
-
const uas = uaSet(lines);
|
|
30
|
-
expect(uas.size).toBe(AI_TRAINING_BOTS.length + AI_RETRIEVAL_BOTS.length);
|
|
31
|
-
});
|
|
32
|
-
it('legacy blockAIBots=true blocks both groups (back-compat)', () => {
|
|
33
|
-
const lines = buildAiBotRobotsLines(undefined, true);
|
|
34
|
-
const uas = uaSet(lines);
|
|
35
|
-
expect(uas.has('GPTBot')).toBe(true);
|
|
36
|
-
expect(uas.has('PerplexityBot')).toBe(true);
|
|
37
|
-
});
|
|
38
|
-
it('a set aiPolicy overrides the legacy flag', () => {
|
|
39
|
-
// Operator opted into nuance: training blocked, retrieval allowed — even
|
|
40
|
-
// though the legacy flag is also on, the nuanced policy wins.
|
|
41
|
-
const lines = buildAiBotRobotsLines({ training: 'block', retrieval: 'allow' }, true);
|
|
42
|
-
const uas = uaSet(lines);
|
|
43
|
-
expect(uas.has('GPTBot')).toBe(true);
|
|
44
|
-
expect(uas.has('PerplexityBot')).toBe(false);
|
|
45
|
-
});
|
|
46
|
-
it('every blocked bot gets a Disallow: / line', () => {
|
|
47
|
-
const lines = buildAiBotRobotsLines({ training: 'block' }, undefined);
|
|
48
|
-
const uaCount = lines.filter((l) => l.startsWith('User-agent: ')).length;
|
|
49
|
-
const disallowCount = lines.filter((l) => l === 'Disallow: /').length;
|
|
50
|
-
expect(disallowCount).toBe(uaCount);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
describe('detectAiBot', () => {
|
|
54
|
-
it('returns null for empty / human user agents', () => {
|
|
55
|
-
expect(detectAiBot(null)).toBeNull();
|
|
56
|
-
expect(detectAiBot(undefined)).toBeNull();
|
|
57
|
-
expect(detectAiBot('')).toBeNull();
|
|
58
|
-
expect(detectAiBot('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120')).toBeNull();
|
|
59
|
-
});
|
|
60
|
-
it('classifies a training crawler', () => {
|
|
61
|
-
expect(detectAiBot('Mozilla/5.0 (compatible; GPTBot/1.1; +https://openai.com/gptbot)')).toEqual({ token: 'GPTBot', category: 'training' });
|
|
62
|
-
expect(detectAiBot('CCBot/2.0 (https://commoncrawl.org/faq/)')).toEqual({
|
|
63
|
-
token: 'CCBot',
|
|
64
|
-
category: 'training',
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
it('classifies a retrieval / answer-engine crawler', () => {
|
|
68
|
-
expect(detectAiBot('Mozilla/5.0 (compatible; PerplexityBot/1.0)')).toEqual({
|
|
69
|
-
token: 'PerplexityBot',
|
|
70
|
-
category: 'retrieval',
|
|
71
|
-
});
|
|
72
|
-
expect(detectAiBot('Mozilla/5.0 ... ChatGPT-User/1.0')).toEqual({
|
|
73
|
-
token: 'ChatGPT-User',
|
|
74
|
-
category: 'retrieval',
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
it('prefers the more specific *-Extended training token over its search namesake', () => {
|
|
78
|
-
expect(detectAiBot('Mozilla/5.0 (compatible; Applebot-Extended/0.1)')).toEqual({
|
|
79
|
-
token: 'Applebot-Extended',
|
|
80
|
-
category: 'training',
|
|
81
|
-
});
|
|
82
|
-
// Plain Applebot (search/Siri) is retrieval, not training.
|
|
83
|
-
expect(detectAiBot('Mozilla/5.0 (compatible; Applebot/0.1)')).toEqual({
|
|
84
|
-
token: 'Applebot',
|
|
85
|
-
category: 'retrieval',
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
it('is case-insensitive', () => {
|
|
89
|
-
expect(detectAiBot('something gptbot something')?.token).toBe('GPTBot');
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
//# sourceMappingURL=ai-bots.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ai-bots.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/ai-bots.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"alt-text.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/seo/alt-text.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { analyzeImageAlts, countMissingAltImages, isDecorativeImgTag } from '../../seo/alt-text.js';
|
|
3
|
-
describe('isDecorativeImgTag', () => {
|
|
4
|
-
it('treats an explicit empty alt as decorative', () => {
|
|
5
|
-
expect(isDecorativeImgTag('<img src="x.jpg" alt="">')).toBe(true);
|
|
6
|
-
expect(isDecorativeImgTag('<img src="x.jpg" alt=" ">')).toBe(true);
|
|
7
|
-
});
|
|
8
|
-
it('treats role=presentation / none / aria-hidden as decorative when alt is absent', () => {
|
|
9
|
-
expect(isDecorativeImgTag('<img src="x.jpg" role="presentation">')).toBe(true);
|
|
10
|
-
expect(isDecorativeImgTag('<img src="x.jpg" role="none">')).toBe(true);
|
|
11
|
-
expect(isDecorativeImgTag('<img src="x.jpg" aria-hidden="true">')).toBe(true);
|
|
12
|
-
});
|
|
13
|
-
it('is not decorative when it has descriptive alt', () => {
|
|
14
|
-
expect(isDecorativeImgTag('<img src="x.jpg" alt="A cat" role="presentation">')).toBe(false);
|
|
15
|
-
expect(isDecorativeImgTag('<img src="x.jpg" alt="A cat">')).toBe(false);
|
|
16
|
-
});
|
|
17
|
-
it('a bare img with no alt and no role is not decorative (it is missing)', () => {
|
|
18
|
-
expect(isDecorativeImgTag('<img src="x.jpg">')).toBe(false);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
describe('analyzeImageAlts', () => {
|
|
22
|
-
it('classifies images into withAlt / decorative / missing', () => {
|
|
23
|
-
const html = [
|
|
24
|
-
'<img src="a.jpg" alt="A photo">', // withAlt
|
|
25
|
-
'<img src="b.jpg" alt="">', // decorative (intentional empty)
|
|
26
|
-
'<img src="c.jpg" role="presentation">', // decorative (marked)
|
|
27
|
-
'<img src="d.jpg">', // missing
|
|
28
|
-
].join('');
|
|
29
|
-
const r = analyzeImageAlts(html);
|
|
30
|
-
expect(r).toMatchObject({ total: 4, withAlt: 1, decorative: 2, missing: 1 });
|
|
31
|
-
expect(r.altTexts).toEqual(['A photo']);
|
|
32
|
-
});
|
|
33
|
-
it('does not mistake hyphenated attributes for alt', () => {
|
|
34
|
-
expect(analyzeImageAlts('<img src="x.jpg" data-default-alt="hi">').missing).toBe(1);
|
|
35
|
-
});
|
|
36
|
-
it('handles empty / non-HTML input', () => {
|
|
37
|
-
expect(analyzeImageAlts('').total).toBe(0);
|
|
38
|
-
expect(analyzeImageAlts(null).missing).toBe(0);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe('countMissingAltImages', () => {
|
|
42
|
-
it('counts only non-decorative images that lack alt', () => {
|
|
43
|
-
const html = '<img src="a.jpg" alt="A"><img src="b.jpg" alt=""><img src="c.jpg"><img src="d.jpg" aria-hidden="true">';
|
|
44
|
-
expect(countMissingAltImages(html)).toBe(1);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
//# sourceMappingURL=alt-text.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"alt-text.test.js","sourceRoot":"","sources":["../../../src/__tests__/seo/alt-text.test.ts"],"names":[],"mappings":"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"}
|