@nextsparkjs/core 0.1.0-beta.188 → 0.1.0-beta.189
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/dist/components/api/keys/ApiKeyDisplay.js +19 -19
- package/dist/components/api/keys/CreateApiKeyDialog.js +21 -21
- package/dist/components/app/layouts/PublicNavbar.d.ts.map +1 -1
- package/dist/components/app/layouts/PublicNavbar.js +34 -16
- package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
- package/dist/components/app/misc/ThemeToggle.js +3 -4
- package/dist/components/auth/SessionCookieRefresher.d.ts +5 -0
- package/dist/components/auth/SessionCookieRefresher.d.ts.map +1 -1
- package/dist/components/auth/SessionCookieRefresher.js +7 -1
- package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
- package/dist/components/auth/forms/LoginForm.js +49 -12
- package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
- package/dist/components/auth/forms/SignupForm.js +4 -3
- package/dist/components/dashboard/block-editor/block-settings-panel.js +1 -1
- package/dist/components/dashboard/block-editor/floating-block-toolbar.js +1 -1
- package/dist/components/dashboard/block-editor/sortable-block.js +1 -1
- package/dist/components/dashboard/layouts/Sidebar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/Sidebar.js +8 -6
- package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/TopNavbar.js +51 -54
- package/dist/components/dashboard/misc/NotificationsDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/NotificationsDropdown.js +17 -15
- package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/SearchDropdown.js +19 -22
- package/dist/components/dashboard/mobile/MobileBottomNav.js +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.js +2 -2
- package/dist/components/dashboard/navigation/DynamicNavigation.js +5 -5
- package/dist/components/devtools/BlockDetailViewer.js +1 -1
- package/dist/components/devtools/BlocksViewer.js +1 -1
- package/dist/components/entities/EntityChildManager.js +5 -5
- package/dist/components/entities/EntityDetailPage.d.ts.map +1 -1
- package/dist/components/entities/EntityDetailPage.js +16 -15
- package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
- package/dist/components/entities/EntityFieldRenderer.js +12 -7
- package/dist/components/entities/EntityPageHeader.js +5 -5
- package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/entities/ErrorBoundary.js +20 -21
- package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -5
- package/dist/components/entities/wrappers/EntityFormWrapper.js +2 -2
- package/dist/components/entities/wrappers/EntityListWrapper.js +3 -3
- package/dist/components/permissions/NoPermission.js +10 -10
- package/dist/components/public/pageBuilder/PageRenderer.d.ts.map +1 -1
- package/dist/components/public/pageBuilder/PageRenderer.js +2 -1
- package/dist/components/settings/SettingsPageSkeleton.js +4 -4
- package/dist/components/settings/layouts/SettingsSidebar.js +6 -6
- package/dist/components/shared/MultiSelectFilter.d.ts +3 -1
- package/dist/components/shared/MultiSelectFilter.d.ts.map +1 -1
- package/dist/components/shared/MultiSelectFilter.js +7 -3
- package/dist/components/shared/SearchInput.d.ts +2 -0
- package/dist/components/shared/SearchInput.d.ts.map +1 -1
- package/dist/components/shared/SearchInput.js +64 -6
- package/dist/components/ui/address-input.js +18 -18
- package/dist/components/ui/audio-upload.js +9 -9
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/combobox.js +4 -4
- package/dist/components/ui/country-select.d.ts.map +1 -1
- package/dist/components/ui/country-select.js +3 -3
- package/dist/components/ui/currency-select.d.ts.map +1 -1
- package/dist/components/ui/currency-select.js +3 -3
- package/dist/components/ui/dynamic-icon.d.ts.map +1 -1
- package/dist/components/ui/dynamic-icon.js +3 -2
- package/dist/components/ui/file-upload.js +7 -7
- package/dist/components/ui/image-upload.js +8 -8
- package/dist/components/ui/multi-select.d.ts +2 -1
- package/dist/components/ui/multi-select.d.ts.map +1 -1
- package/dist/components/ui/multi-select.js +4 -3
- package/dist/components/ui/phone-input.d.ts.map +1 -1
- package/dist/components/ui/phone-input.js +3 -3
- package/dist/components/ui/relation-display.js +1 -1
- package/dist/components/ui/simple-relation-select.d.ts +2 -1
- package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
- package/dist/components/ui/simple-relation-select.js +7 -6
- package/dist/components/ui/tags-input.d.ts.map +1 -1
- package/dist/components/ui/tags-input.js +1 -1
- package/dist/components/ui/timezone-select.d.ts.map +1 -1
- package/dist/components/ui/timezone-select.js +3 -3
- package/dist/components/ui/user-display.js +4 -4
- package/dist/components/ui/user-select.d.ts.map +1 -1
- package/dist/components/ui/user-select.js +9 -9
- package/dist/components/ui/video-upload.js +9 -9
- package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
- package/dist/contexts/SubscriptionContext.js +5 -1
- package/dist/contexts/TeamContext.d.ts.map +1 -1
- package/dist/contexts/TeamContext.js +83 -26
- package/dist/emails/otp-verification.d.ts.map +1 -1
- package/dist/emails/otp-verification.js +3 -2
- package/dist/hooks/useAccountPreferencesSync.d.ts +13 -0
- package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -0
- package/dist/hooks/useAccountPreferencesSync.js +95 -0
- package/dist/hooks/useAuth.d.ts +202 -15
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +49 -13
- package/dist/hooks/useEntityConfig.js +2 -2
- package/dist/hooks/useEntitySearch.js +10 -10
- package/dist/hooks/useNotifications.js +12 -12
- package/dist/hooks/usePrefetch.d.ts.map +1 -1
- package/dist/hooks/usePrefetch.js +6 -2
- package/dist/hooks/useSearch.js +15 -15
- package/dist/hooks/useSessionCookieRefresh.d.ts +18 -1
- package/dist/hooks/useSessionCookieRefresh.d.ts.map +1 -1
- package/dist/hooks/useSessionCookieRefresh.js +17 -4
- package/dist/hooks/useSessionHint.d.ts +12 -0
- package/dist/hooks/useSessionHint.d.ts.map +1 -0
- package/dist/hooks/useSessionHint.js +15 -0
- package/dist/hooks/useTranslationPreload.js +6 -6
- package/dist/i18n.d.ts +13 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +2 -27
- package/dist/lib/actions/entity.actions.d.ts.map +1 -1
- package/dist/lib/actions/entity.actions.js +3 -2
- package/dist/lib/api/auth/dual-auth.d.ts +4 -1
- package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
- package/dist/lib/api/auth/dual-auth.js +5 -16
- package/dist/lib/api/entities.js +33 -33
- package/dist/lib/api/keys.d.ts +27 -27
- package/dist/lib/api/keys.js +27 -27
- package/dist/lib/auth/callback-url.d.ts +11 -0
- package/dist/lib/auth/callback-url.d.ts.map +1 -0
- package/dist/lib/auth/callback-url.js +14 -0
- package/dist/lib/auth/otp-config.d.ts +55 -0
- package/dist/lib/auth/otp-config.d.ts.map +1 -0
- package/dist/lib/auth/otp-config.js +48 -0
- package/dist/lib/auth/registration-helpers.d.ts.map +1 -1
- package/dist/lib/auth/registration-helpers.js +3 -1
- package/dist/lib/auth/session-hint.d.ts +31 -0
- package/dist/lib/auth/session-hint.d.ts.map +1 -0
- package/dist/lib/auth/session-hint.js +37 -0
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +6 -4
- package/dist/lib/blocks/loader.d.ts +3 -11
- package/dist/lib/blocks/loader.d.ts.map +1 -1
- package/dist/lib/blocks/loader.js +1 -9
- package/dist/lib/blocks/loader.server.d.ts +18 -0
- package/dist/lib/blocks/loader.server.d.ts.map +1 -0
- package/dist/lib/blocks/loader.server.js +11 -0
- package/dist/lib/blocks/sanitize-html.d.ts +31 -0
- package/dist/lib/blocks/sanitize-html.d.ts.map +1 -0
- package/dist/lib/blocks/sanitize-html.js +60 -0
- package/dist/lib/config/config-sync.d.ts +1 -0
- package/dist/lib/config/config-sync.d.ts.map +1 -1
- package/dist/lib/config/config-sync.js +4 -1
- package/dist/lib/config/types.d.ts +48 -0
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/email/types.d.ts +6 -0
- package/dist/lib/email/types.d.ts.map +1 -1
- package/dist/lib/entities/serialization.d.ts.map +1 -1
- package/dist/lib/entities/serialization.js +3 -6
- package/dist/lib/icons.d.ts +12 -0
- package/dist/lib/icons.d.ts.map +1 -0
- package/dist/lib/icons.js +30 -0
- package/dist/lib/locale.d.ts +25 -1
- package/dist/lib/locale.d.ts.map +1 -1
- package/dist/lib/locale.js +49 -35
- package/dist/lib/mcp/engine.js +1 -1
- package/dist/lib/mcp/errors.js +17 -17
- package/dist/lib/mcp/schema-builder.js +16 -16
- package/dist/lib/mcp/tool-generator.js +18 -18
- package/dist/lib/search-highlighting.d.ts +7 -0
- package/dist/lib/search-highlighting.d.ts.map +1 -1
- package/dist/lib/search-highlighting.js +6 -2
- package/dist/lib/selectors/core-selectors.d.ts +2 -0
- package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/auth.selectors.d.ts +1 -0
- package/dist/lib/selectors/domains/auth.selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/auth.selectors.js +1 -0
- package/dist/lib/selectors/domains/entities.selectors.d.ts +2 -0
- package/dist/lib/selectors/domains/entities.selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/entities.selectors.js +2 -0
- package/dist/lib/selectors/selectors.d.ts +4 -0
- package/dist/lib/selectors/selectors.d.ts.map +1 -1
- package/dist/lib/services/block.service.js +1 -1
- package/dist/lib/teams/active-team-cookie.d.ts +24 -0
- package/dist/lib/teams/active-team-cookie.d.ts.map +1 -0
- package/dist/lib/teams/active-team-cookie.js +17 -0
- package/dist/lib/teams/dashboard-team.d.ts +20 -0
- package/dist/lib/teams/dashboard-team.d.ts.map +1 -0
- package/dist/lib/teams/dashboard-team.js +38 -0
- package/dist/lib/teams/schema.d.ts.map +1 -1
- package/dist/lib/teams/schema.js +1 -1
- package/dist/lib/template-resolver.d.ts.map +1 -1
- package/dist/lib/template-resolver.js +0 -1
- package/dist/lib/theme/get-default-theme-mode.d.ts +7 -4
- package/dist/lib/theme/get-default-theme-mode.d.ts.map +1 -1
- package/dist/lib/theme/get-default-theme-mode.js +2 -44
- package/dist/messages/de/auth.json +4 -2
- package/dist/messages/de/common.json +83 -3
- package/dist/messages/de/email.json +1 -1
- package/dist/messages/de/index.d.ts +87 -0
- package/dist/messages/de/index.d.ts.map +1 -1
- package/dist/messages/de/settings.json +5 -0
- package/dist/messages/en/auth.json +4 -2
- package/dist/messages/en/common.json +83 -3
- package/dist/messages/en/email.json +1 -1
- package/dist/messages/en/index.d.ts +86 -0
- package/dist/messages/en/index.d.ts.map +1 -1
- package/dist/messages/en/settings.json +4 -0
- package/dist/messages/es/auth.json +4 -2
- package/dist/messages/es/common.json +83 -3
- package/dist/messages/es/email.json +1 -1
- package/dist/messages/es/index.d.ts +86 -0
- package/dist/messages/es/index.d.ts.map +1 -1
- package/dist/messages/es/settings.json +4 -0
- package/dist/messages/fr/auth.json +4 -2
- package/dist/messages/fr/common.json +83 -3
- package/dist/messages/fr/email.json +1 -1
- package/dist/messages/fr/index.d.ts +87 -0
- package/dist/messages/fr/index.d.ts.map +1 -1
- package/dist/messages/fr/settings.json +5 -0
- package/dist/messages/it/auth.json +4 -2
- package/dist/messages/it/common.json +83 -3
- package/dist/messages/it/email.json +1 -1
- package/dist/messages/it/index.d.ts +87 -0
- package/dist/messages/it/index.d.ts.map +1 -1
- package/dist/messages/it/settings.json +5 -0
- package/dist/messages/pt/auth.json +4 -2
- package/dist/messages/pt/common.json +83 -3
- package/dist/messages/pt/email.json +1 -1
- package/dist/messages/pt/index.d.ts +87 -0
- package/dist/messages/pt/index.d.ts.map +1 -1
- package/dist/messages/pt/settings.json +5 -0
- package/dist/nextspark-registries.d.ts +54 -0
- package/dist/providers/DashboardProviders.d.ts +13 -10
- package/dist/providers/DashboardProviders.d.ts.map +1 -1
- package/dist/providers/DashboardProviders.js +7 -1
- package/dist/templates/app/(auth)/forgot-password/page.tsx +2 -2
- package/dist/templates/app/(auth)/reset-password/page.tsx +6 -6
- package/dist/templates/app/403/page.tsx +6 -6
- package/dist/templates/app/api/v1/teams/switch/route.ts +24 -5
- package/dist/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
- package/dist/templates/app/dashboard/(main)/layout.tsx +4 -3
- package/dist/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
- package/dist/templates/app/dashboard/settings/profile/page.tsx +7 -6
- package/dist/templates/app/dashboard/settings/security/page.tsx +5 -4
- package/dist/templates/app/layout.ppr.tsx +8 -8
- package/dist/templates/app/layout.tsx +12 -17
- package/dist/templates/blocks/cta-section/component.tsx +5 -2
- package/dist/templates/blocks/cta-section/config.ts +3 -2
- package/dist/templates/blocks/cta-section/fields.ts +2 -2
- package/dist/templates/blocks/cta-section/schema.ts +2 -2
- package/dist/templates/blocks/features-grid/component.tsx +10 -2
- package/dist/templates/blocks/features-grid/config.ts +3 -2
- package/dist/templates/blocks/features-grid/fields.ts +2 -2
- package/dist/templates/blocks/features-grid/schema.ts +2 -2
- package/dist/templates/blocks/hero/component.tsx +6 -3
- package/dist/templates/blocks/hero/config.ts +3 -2
- package/dist/templates/blocks/hero/fields.ts +2 -2
- package/dist/templates/blocks/hero/schema.ts +2 -2
- package/dist/templates/blocks/testimonials/component.tsx +6 -3
- package/dist/templates/blocks/testimonials/config.ts +3 -2
- package/dist/templates/blocks/testimonials/fields.ts +2 -2
- package/dist/templates/blocks/testimonials/schema.ts +2 -2
- package/dist/templates/blocks/text-content/component.tsx +7 -3
- package/dist/templates/blocks/text-content/config.ts +3 -2
- package/dist/templates/blocks/text-content/fields.ts +2 -2
- package/dist/templates/blocks/text-content/schema.ts +2 -2
- package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
- package/dist/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
- package/dist/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
- package/dist/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/config/app.config.ts +8 -0
- package/dist/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
- package/dist/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
- package/dist/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
- package/dist/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
- package/dist/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
- package/dist/templates/features/blog/blocks/post-content/component.tsx +5 -1
- package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/dist/templates/features/pages/blocks/hero/component.tsx +3 -0
- package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/dist/templates/proxy.ts +138 -53
- package/dist/types/blocks.d.ts.map +1 -1
- package/dist/types/blocks.js +1 -1
- package/dist/types/task.types.d.ts +1 -1
- package/dist/types/task.types.js +7 -7
- package/dist/utils/dev/TranslationDebugger.js +2 -2
- package/package.json +14 -5
- package/scripts/build/registry/__tests__/block-registry.test.mjs +73 -0
- package/scripts/build/registry/__tests__/icons-discovery.test.mjs +130 -0
- package/scripts/build/registry/__tests__/identifier.test.mjs +65 -0
- package/scripts/build/registry/__tests__/page-generator.test.mjs +430 -0
- package/scripts/build/registry/__tests__/scheduled-actions-registry.test.mjs +41 -0
- package/scripts/build/registry/__tests__/template-registry.test.mjs +89 -0
- package/scripts/build/registry/discovery/icons.mjs +275 -0
- package/scripts/build/registry/discovery/index.mjs +1 -0
- package/scripts/build/registry/generators/block-registry.mjs +203 -55
- package/scripts/build/registry/generators/feature-registry.mjs +9 -2
- package/scripts/build/registry/generators/icon-registry.mjs +56 -0
- package/scripts/build/registry/generators/identifier.mjs +28 -0
- package/scripts/build/registry/generators/index.mjs +1 -0
- package/scripts/build/registry/generators/plugin-registry.mjs +4 -3
- package/scripts/build/registry/generators/scheduled-actions-registry.mjs +4 -2
- package/scripts/build/registry/generators/template-registry.mjs +49 -41
- package/scripts/build/registry/generators/theme-registry.mjs +6 -7
- package/scripts/build/registry/post-build/page-generator.mjs +380 -59
- package/scripts/build/registry.mjs +9 -1
- package/templates/app/(auth)/forgot-password/page.tsx +2 -2
- package/templates/app/(auth)/reset-password/page.tsx +6 -6
- package/templates/app/403/page.tsx +6 -6
- package/templates/app/api/v1/teams/switch/route.ts +24 -5
- package/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
- package/templates/app/dashboard/(main)/layout.tsx +4 -3
- package/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
- package/templates/app/dashboard/settings/profile/page.tsx +7 -6
- package/templates/app/dashboard/settings/security/page.tsx +5 -4
- package/templates/app/layout.ppr.tsx +8 -8
- package/templates/app/layout.tsx +12 -17
- package/templates/blocks/cta-section/component.tsx +5 -2
- package/templates/blocks/cta-section/config.ts +3 -2
- package/templates/blocks/cta-section/fields.ts +2 -2
- package/templates/blocks/cta-section/schema.ts +2 -2
- package/templates/blocks/features-grid/component.tsx +10 -2
- package/templates/blocks/features-grid/config.ts +3 -2
- package/templates/blocks/features-grid/fields.ts +2 -2
- package/templates/blocks/features-grid/schema.ts +2 -2
- package/templates/blocks/hero/component.tsx +6 -3
- package/templates/blocks/hero/config.ts +3 -2
- package/templates/blocks/hero/fields.ts +2 -2
- package/templates/blocks/hero/schema.ts +2 -2
- package/templates/blocks/testimonials/component.tsx +6 -3
- package/templates/blocks/testimonials/config.ts +3 -2
- package/templates/blocks/testimonials/fields.ts +2 -2
- package/templates/blocks/testimonials/schema.ts +2 -2
- package/templates/blocks/text-content/component.tsx +7 -3
- package/templates/blocks/text-content/config.ts +3 -2
- package/templates/blocks/text-content/fields.ts +2 -2
- package/templates/blocks/text-content/schema.ts +2 -2
- package/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
- package/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
- package/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
- package/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
- package/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
- package/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
- package/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
- package/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
- package/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
- package/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
- package/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
- package/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
- package/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
- package/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
- package/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
- package/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
- package/templates/contents/themes/starter/config/app.config.ts +8 -0
- package/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
- package/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
- package/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
- package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
- package/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
- package/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
- package/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
- package/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
- package/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
- package/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
- package/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
- package/templates/features/blog/blocks/post-content/component.tsx +5 -1
- package/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/templates/features/pages/blocks/hero/component.tsx +3 -0
- package/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/templates/proxy.ts +138 -53
- package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.client.ts +9 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.lazy.ts +5 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/icon-registry.ts +42 -0
- package/tests/jest/__mocks__/next-intl-server.js +85 -5
- package/tests/jest/__mocks__/next-server.js +32 -0
package/dist/lib/api/entities.js
CHANGED
|
@@ -79,13 +79,13 @@ class EntityApiClient {
|
|
|
79
79
|
});
|
|
80
80
|
if (!response.ok) {
|
|
81
81
|
const errorData = await response.json().catch(() => ({}));
|
|
82
|
-
let userMessage = `
|
|
82
|
+
let userMessage = `Failed to load ${entityType}`;
|
|
83
83
|
if (response.status === 401) {
|
|
84
|
-
userMessage = "
|
|
84
|
+
userMessage = "You do not have permission to access this data. Please sign in again.";
|
|
85
85
|
} else if (response.status === 403) {
|
|
86
|
-
userMessage = "
|
|
86
|
+
userMessage = "You do not have the necessary permissions to perform this action.";
|
|
87
87
|
} else if (response.status === 404) {
|
|
88
|
-
userMessage = "
|
|
88
|
+
userMessage = "The requested data was not found.";
|
|
89
89
|
} else if (response.status === 400 && errorData.code === "TEAM_CONTEXT_REQUIRED") {
|
|
90
90
|
console.warn("[EntityApiClient] Team context not ready yet, returning empty list");
|
|
91
91
|
return {
|
|
@@ -102,7 +102,7 @@ class EntityApiClient {
|
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
104
|
} else if (response.status >= 500) {
|
|
105
|
-
userMessage = "
|
|
105
|
+
userMessage = "Internal server error. Please try again later.";
|
|
106
106
|
} else if (errorData.message && !errorData.message.includes("API key")) {
|
|
107
107
|
userMessage = errorData.message;
|
|
108
108
|
}
|
|
@@ -127,15 +127,15 @@ class EntityApiClient {
|
|
|
127
127
|
});
|
|
128
128
|
if (!response.ok) {
|
|
129
129
|
const errorData = await response.json().catch(() => ({}));
|
|
130
|
-
let userMessage = `
|
|
130
|
+
let userMessage = `Failed to load ${entityType}`;
|
|
131
131
|
if (response.status === 401) {
|
|
132
|
-
userMessage = "
|
|
132
|
+
userMessage = "You do not have permission to access this data. Please sign in again.";
|
|
133
133
|
} else if (response.status === 403) {
|
|
134
|
-
userMessage = "
|
|
134
|
+
userMessage = "You do not have the necessary permissions to perform this action.";
|
|
135
135
|
} else if (response.status === 404) {
|
|
136
|
-
userMessage = "
|
|
136
|
+
userMessage = "The requested item was not found.";
|
|
137
137
|
} else if (response.status >= 500) {
|
|
138
|
-
userMessage = "
|
|
138
|
+
userMessage = "Internal server error. Please try again later.";
|
|
139
139
|
} else if (errorData.message && !errorData.message.includes("API key")) {
|
|
140
140
|
userMessage = errorData.message;
|
|
141
141
|
}
|
|
@@ -158,15 +158,15 @@ class EntityApiClient {
|
|
|
158
158
|
});
|
|
159
159
|
if (!response.ok) {
|
|
160
160
|
const errorData = await response.json().catch(() => ({}));
|
|
161
|
-
let userMessage = `
|
|
161
|
+
let userMessage = `Failed to create ${entityType}`;
|
|
162
162
|
if (response.status === 401) {
|
|
163
|
-
userMessage = "
|
|
163
|
+
userMessage = "You do not have permission to create this item. Please sign in again.";
|
|
164
164
|
} else if (response.status === 403) {
|
|
165
|
-
userMessage = "
|
|
165
|
+
userMessage = "You do not have the necessary permissions to create this item.";
|
|
166
166
|
} else if (response.status === 400) {
|
|
167
|
-
userMessage = "
|
|
167
|
+
userMessage = "The provided data is not valid. Please review the form.";
|
|
168
168
|
} else if (response.status >= 500) {
|
|
169
|
-
userMessage = "
|
|
169
|
+
userMessage = "Internal server error. Please try again later.";
|
|
170
170
|
} else if (errorData.message && !errorData.message.includes("API key")) {
|
|
171
171
|
userMessage = errorData.message;
|
|
172
172
|
}
|
|
@@ -189,17 +189,17 @@ class EntityApiClient {
|
|
|
189
189
|
});
|
|
190
190
|
if (!response.ok) {
|
|
191
191
|
const errorData = await response.json().catch(() => ({}));
|
|
192
|
-
let userMessage = `
|
|
192
|
+
let userMessage = `Failed to update ${entityType}`;
|
|
193
193
|
if (response.status === 401) {
|
|
194
|
-
userMessage = "
|
|
194
|
+
userMessage = "You do not have permission to update this item. Please sign in again.";
|
|
195
195
|
} else if (response.status === 403) {
|
|
196
|
-
userMessage = "
|
|
196
|
+
userMessage = "You do not have the necessary permissions to update this item.";
|
|
197
197
|
} else if (response.status === 404) {
|
|
198
|
-
userMessage = "
|
|
198
|
+
userMessage = "The item you are trying to update was not found.";
|
|
199
199
|
} else if (response.status === 400) {
|
|
200
|
-
userMessage = "
|
|
200
|
+
userMessage = "The provided data is not valid. Please review the form.";
|
|
201
201
|
} else if (response.status >= 500) {
|
|
202
|
-
userMessage = "
|
|
202
|
+
userMessage = "Internal server error. Please try again later.";
|
|
203
203
|
} else if (errorData.message && !errorData.message.includes("API key")) {
|
|
204
204
|
userMessage = errorData.message;
|
|
205
205
|
}
|
|
@@ -221,15 +221,15 @@ class EntityApiClient {
|
|
|
221
221
|
});
|
|
222
222
|
if (!response.ok) {
|
|
223
223
|
const errorData = await response.json().catch(() => ({}));
|
|
224
|
-
let userMessage = `
|
|
224
|
+
let userMessage = `Failed to delete ${entityType}`;
|
|
225
225
|
if (response.status === 401) {
|
|
226
|
-
userMessage = "
|
|
226
|
+
userMessage = "You do not have permission to delete this item. Please sign in again.";
|
|
227
227
|
} else if (response.status === 403) {
|
|
228
|
-
userMessage = "
|
|
228
|
+
userMessage = "You do not have the necessary permissions to delete this item.";
|
|
229
229
|
} else if (response.status === 404) {
|
|
230
|
-
userMessage = "
|
|
230
|
+
userMessage = "The item you are trying to delete was not found.";
|
|
231
231
|
} else if (response.status >= 500) {
|
|
232
|
-
userMessage = "
|
|
232
|
+
userMessage = "Internal server error. Please try again later.";
|
|
233
233
|
} else if (errorData.message && !errorData.message.includes("API key")) {
|
|
234
234
|
userMessage = errorData.message;
|
|
235
235
|
}
|
|
@@ -333,8 +333,8 @@ class EntityApiClient {
|
|
|
333
333
|
if (entityConfig.features.canDelete) {
|
|
334
334
|
operations.push({
|
|
335
335
|
id: "bulk-delete",
|
|
336
|
-
name: "
|
|
337
|
-
description: "
|
|
336
|
+
name: "Delete Selected",
|
|
337
|
+
description: "Delete multiple items at once",
|
|
338
338
|
icon: "trash",
|
|
339
339
|
requiresConfirmation: true
|
|
340
340
|
});
|
|
@@ -342,15 +342,15 @@ class EntityApiClient {
|
|
|
342
342
|
if (entityConfig.features.canEdit) {
|
|
343
343
|
operations.push({
|
|
344
344
|
id: "bulk-edit",
|
|
345
|
-
name: "
|
|
346
|
-
description: "
|
|
345
|
+
name: "Edit Selected",
|
|
346
|
+
description: "Update multiple items at once",
|
|
347
347
|
icon: "edit"
|
|
348
348
|
});
|
|
349
349
|
}
|
|
350
350
|
operations.push({
|
|
351
351
|
id: "bulk-export",
|
|
352
|
-
name: "
|
|
353
|
-
description: "
|
|
352
|
+
name: "Export",
|
|
353
|
+
description: "Export selected data",
|
|
354
354
|
icon: "download"
|
|
355
355
|
});
|
|
356
356
|
return operations;
|
|
@@ -376,7 +376,7 @@ class EntityApiClient {
|
|
|
376
376
|
});
|
|
377
377
|
if (!response.ok) {
|
|
378
378
|
const errorData = await response.json().catch(() => ({}));
|
|
379
|
-
throw new Error(errorData.message || `Error
|
|
379
|
+
throw new Error(errorData.message || `Error executing operation ${operationId}`);
|
|
380
380
|
}
|
|
381
381
|
const result = await response.json();
|
|
382
382
|
return result.data;
|
package/dist/lib/api/keys.d.ts
CHANGED
|
@@ -39,24 +39,24 @@ export declare class ApiKeyManager {
|
|
|
39
39
|
* Definición de scopes disponibles para API keys
|
|
40
40
|
*/
|
|
41
41
|
export declare const API_SCOPES: {
|
|
42
|
-
readonly 'users:read': "
|
|
43
|
-
readonly 'users:write': "
|
|
44
|
-
readonly 'users:delete': "
|
|
45
|
-
readonly 'tasks:read': "
|
|
46
|
-
readonly 'tasks:write': "
|
|
47
|
-
readonly 'tasks:delete': "
|
|
48
|
-
readonly 'media:read': "
|
|
49
|
-
readonly 'media:write': "
|
|
50
|
-
readonly 'media:delete': "
|
|
51
|
-
readonly 'teams:read': "
|
|
52
|
-
readonly 'teams:write': "
|
|
53
|
-
readonly 'teams:delete': "
|
|
54
|
-
readonly 'billing:read': "
|
|
55
|
-
readonly 'billing:write': "
|
|
56
|
-
readonly 'admin:api-keys': "
|
|
57
|
-
readonly 'admin:users': "
|
|
58
|
-
readonly 'admin:devtools': "
|
|
59
|
-
readonly '*': "
|
|
42
|
+
readonly 'users:read': "Read user information";
|
|
43
|
+
readonly 'users:write': "Create and update users";
|
|
44
|
+
readonly 'users:delete': "Delete users";
|
|
45
|
+
readonly 'tasks:read': "Read tasks";
|
|
46
|
+
readonly 'tasks:write': "Create and update tasks";
|
|
47
|
+
readonly 'tasks:delete': "Delete tasks";
|
|
48
|
+
readonly 'media:read': "Read file and media information";
|
|
49
|
+
readonly 'media:write': "Upload and update files";
|
|
50
|
+
readonly 'media:delete': "Delete files";
|
|
51
|
+
readonly 'teams:read': "Read teams, members and invitations";
|
|
52
|
+
readonly 'teams:write': "Create and update teams, members and invitations";
|
|
53
|
+
readonly 'teams:delete': "Delete teams";
|
|
54
|
+
readonly 'billing:read': "Read subscriptions, invoices and usage";
|
|
55
|
+
readonly 'billing:write': "Manage subscriptions, checkout, plan changes and usage";
|
|
56
|
+
readonly 'admin:api-keys': "Manage API keys";
|
|
57
|
+
readonly 'admin:users': "Full user administration";
|
|
58
|
+
readonly 'admin:devtools': "Access to DevTools APIs (registries, testing, scheduled actions)";
|
|
59
|
+
readonly '*': "Full access (superadmin only)";
|
|
60
60
|
};
|
|
61
61
|
export type ApiScope = keyof typeof API_SCOPES;
|
|
62
62
|
/**
|
|
@@ -79,33 +79,33 @@ export declare function getAppApiScopes(): Record<string, string>;
|
|
|
79
79
|
*/
|
|
80
80
|
export declare const SCOPE_CATEGORIES: {
|
|
81
81
|
readonly users: {
|
|
82
|
-
readonly name: "
|
|
83
|
-
readonly description: "
|
|
82
|
+
readonly name: "Users";
|
|
83
|
+
readonly description: "System user management";
|
|
84
84
|
readonly scopes: ApiScope[];
|
|
85
85
|
};
|
|
86
86
|
readonly tasks: {
|
|
87
87
|
readonly name: "Tasks";
|
|
88
|
-
readonly description: "
|
|
88
|
+
readonly description: "Task and TODO management";
|
|
89
89
|
readonly scopes: ApiScope[];
|
|
90
90
|
};
|
|
91
91
|
readonly teams: {
|
|
92
92
|
readonly name: "Teams";
|
|
93
|
-
readonly description: "
|
|
93
|
+
readonly description: "Teams, members and invitations";
|
|
94
94
|
readonly scopes: ApiScope[];
|
|
95
95
|
};
|
|
96
96
|
readonly billing: {
|
|
97
97
|
readonly name: "Billing";
|
|
98
|
-
readonly description: "
|
|
98
|
+
readonly description: "Subscriptions, invoices, usage and plans";
|
|
99
99
|
readonly scopes: ApiScope[];
|
|
100
100
|
};
|
|
101
101
|
readonly admin: {
|
|
102
|
-
readonly name: "
|
|
103
|
-
readonly description: "
|
|
102
|
+
readonly name: "Administration";
|
|
103
|
+
readonly description: "Administrative functions";
|
|
104
104
|
readonly scopes: ApiScope[];
|
|
105
105
|
};
|
|
106
106
|
readonly system: {
|
|
107
|
-
readonly name: "
|
|
108
|
-
readonly description: "
|
|
107
|
+
readonly name: "System";
|
|
108
|
+
readonly description: "Full system access";
|
|
109
109
|
readonly scopes: ApiScope[];
|
|
110
110
|
};
|
|
111
111
|
};
|
package/dist/lib/api/keys.js
CHANGED
|
@@ -70,30 +70,30 @@ class ApiKeyManager {
|
|
|
70
70
|
}
|
|
71
71
|
const API_SCOPES = {
|
|
72
72
|
// Usuarios
|
|
73
|
-
"users:read": "
|
|
74
|
-
"users:write": "
|
|
75
|
-
"users:delete": "
|
|
73
|
+
"users:read": "Read user information",
|
|
74
|
+
"users:write": "Create and update users",
|
|
75
|
+
"users:delete": "Delete users",
|
|
76
76
|
// Tasks
|
|
77
|
-
"tasks:read": "
|
|
78
|
-
"tasks:write": "
|
|
79
|
-
"tasks:delete": "
|
|
77
|
+
"tasks:read": "Read tasks",
|
|
78
|
+
"tasks:write": "Create and update tasks",
|
|
79
|
+
"tasks:delete": "Delete tasks",
|
|
80
80
|
// Media (archivos, imágenes, videos)
|
|
81
|
-
"media:read": "
|
|
82
|
-
"media:write": "
|
|
83
|
-
"media:delete": "
|
|
81
|
+
"media:read": "Read file and media information",
|
|
82
|
+
"media:write": "Upload and update files",
|
|
83
|
+
"media:delete": "Delete files",
|
|
84
84
|
// Teams (equipos, miembros e invitaciones)
|
|
85
|
-
"teams:read": "
|
|
86
|
-
"teams:write": "
|
|
87
|
-
"teams:delete": "
|
|
85
|
+
"teams:read": "Read teams, members and invitations",
|
|
86
|
+
"teams:write": "Create and update teams, members and invitations",
|
|
87
|
+
"teams:delete": "Delete teams",
|
|
88
88
|
// Billing (suscripciones, facturas, uso y planes)
|
|
89
|
-
"billing:read": "
|
|
90
|
-
"billing:write": "
|
|
89
|
+
"billing:read": "Read subscriptions, invoices and usage",
|
|
90
|
+
"billing:write": "Manage subscriptions, checkout, plan changes and usage",
|
|
91
91
|
// Administración
|
|
92
|
-
"admin:api-keys": "
|
|
93
|
-
"admin:users": "
|
|
94
|
-
"admin:devtools": "
|
|
92
|
+
"admin:api-keys": "Manage API keys",
|
|
93
|
+
"admin:users": "Full user administration",
|
|
94
|
+
"admin:devtools": "Access to DevTools APIs (registries, testing, scheduled actions)",
|
|
95
95
|
// Comodín (solo para superadmins)
|
|
96
|
-
"*": "
|
|
96
|
+
"*": "Full access (superadmin only)"
|
|
97
97
|
};
|
|
98
98
|
function getApiScopes() {
|
|
99
99
|
var _a;
|
|
@@ -108,33 +108,33 @@ function getAppApiScopes() {
|
|
|
108
108
|
}
|
|
109
109
|
const SCOPE_CATEGORIES = {
|
|
110
110
|
users: {
|
|
111
|
-
name: "
|
|
112
|
-
description: "
|
|
111
|
+
name: "Users",
|
|
112
|
+
description: "System user management",
|
|
113
113
|
scopes: ["users:read", "users:write", "users:delete"]
|
|
114
114
|
},
|
|
115
115
|
tasks: {
|
|
116
116
|
name: "Tasks",
|
|
117
|
-
description: "
|
|
117
|
+
description: "Task and TODO management",
|
|
118
118
|
scopes: ["tasks:read", "tasks:write", "tasks:delete"]
|
|
119
119
|
},
|
|
120
120
|
teams: {
|
|
121
121
|
name: "Teams",
|
|
122
|
-
description: "
|
|
122
|
+
description: "Teams, members and invitations",
|
|
123
123
|
scopes: ["teams:read", "teams:write", "teams:delete"]
|
|
124
124
|
},
|
|
125
125
|
billing: {
|
|
126
126
|
name: "Billing",
|
|
127
|
-
description: "
|
|
127
|
+
description: "Subscriptions, invoices, usage and plans",
|
|
128
128
|
scopes: ["billing:read", "billing:write"]
|
|
129
129
|
},
|
|
130
130
|
admin: {
|
|
131
|
-
name: "
|
|
132
|
-
description: "
|
|
131
|
+
name: "Administration",
|
|
132
|
+
description: "Administrative functions",
|
|
133
133
|
scopes: ["admin:api-keys", "admin:users", "admin:devtools"]
|
|
134
134
|
},
|
|
135
135
|
system: {
|
|
136
|
-
name: "
|
|
137
|
-
description: "
|
|
136
|
+
name: "System",
|
|
137
|
+
description: "Full system access",
|
|
138
138
|
scopes: ["*"]
|
|
139
139
|
}
|
|
140
140
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Callback URL
|
|
3
|
+
*
|
|
4
|
+
* Where sign-in sends the user afterwards. `callbackUrl` arrives in the login
|
|
5
|
+
* URL, where anyone can write it, so only a path on this app counts: `//host`,
|
|
6
|
+
* `/\host` or an absolute URL would take the user to another site right after
|
|
7
|
+
* they authenticate.
|
|
8
|
+
*/
|
|
9
|
+
/** The path, query and hash of an in-app callback, or null for anything else. */
|
|
10
|
+
export declare function safeCallbackPath(value: string | null | undefined): string | null;
|
|
11
|
+
//# sourceMappingURL=callback-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback-url.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/callback-url.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAWhF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const PLACEHOLDER_ORIGIN = "http://callback.invalid";
|
|
2
|
+
function safeCallbackPath(value) {
|
|
3
|
+
if (!value || !value.startsWith("/")) return null;
|
|
4
|
+
try {
|
|
5
|
+
const url = new URL(value, PLACEHOLDER_ORIGIN);
|
|
6
|
+
const path = `${url.pathname}${url.search}${url.hash}`;
|
|
7
|
+
return url.origin === PLACEHOLDER_ORIGIN && !path.startsWith("//") ? path : null;
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
safeCallbackPath
|
|
14
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email OTP Config Resolution
|
|
3
|
+
*
|
|
4
|
+
* Turns the (optional, partially specified) `auth.otp` block of the merged app
|
|
5
|
+
* config into the concrete values handed to Better Auth's emailOTP plugin. Pure
|
|
6
|
+
* function — no side effects besides a `console.warn` on invalid input — so it
|
|
7
|
+
* is safe to import from client code too.
|
|
8
|
+
*
|
|
9
|
+
* Both numbers are read by the server (the plugin) and by the login form (the
|
|
10
|
+
* notice that counts the code down, and the length the input accepts). They
|
|
11
|
+
* live here so the two agree by construction: a duplicated literal is how the
|
|
12
|
+
* UI ends up promising five minutes for a code that lasts two.
|
|
13
|
+
*
|
|
14
|
+
* Resolution rules:
|
|
15
|
+
* - Every field falls back to the core default when missing.
|
|
16
|
+
* - Non-positive / non-finite values are rejected (warning) → default.
|
|
17
|
+
* - `otpLength` is additionally bounded to what Better Auth can generate.
|
|
18
|
+
*/
|
|
19
|
+
import type { AuthConfig } from '../config/types';
|
|
20
|
+
export interface ResolvedOtpConfig {
|
|
21
|
+
/** Lifetime of an emailed code, in seconds. */
|
|
22
|
+
expiresIn: number;
|
|
23
|
+
/** Number of digits in an emailed code. */
|
|
24
|
+
otpLength: number;
|
|
25
|
+
}
|
|
26
|
+
export declare const DEFAULT_OTP_CONFIG: ResolvedOtpConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the email-OTP configuration the app runs with.
|
|
29
|
+
*
|
|
30
|
+
* @param authConfig - The merged `auth` config (core defaults + theme overrides).
|
|
31
|
+
* Only its `otp` block is read; `undefined`/`null` is
|
|
32
|
+
* allowed and yields the defaults.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveOtpConfig(authConfig?: Pick<AuthConfig, 'otp'> | null): ResolvedOtpConfig;
|
|
35
|
+
/**
|
|
36
|
+
* Seconds left before a code sent at `sentAt` expires, between 0 and the code's
|
|
37
|
+
* lifetime: a clock set back after the request would otherwise count more time
|
|
38
|
+
* than the server gives the code.
|
|
39
|
+
*
|
|
40
|
+
* @param sentAt - Epoch milliseconds of the moment the code was requested.
|
|
41
|
+
* @param expiresIn - Code lifetime in seconds.
|
|
42
|
+
* @param now - Epoch milliseconds to measure against (injectable for tests).
|
|
43
|
+
*/
|
|
44
|
+
export declare function getOtpSecondsRemaining(sentAt: number, expiresIn: number, now?: number): number;
|
|
45
|
+
/**
|
|
46
|
+
* Format a remaining-seconds count as `m:ss`, always with both parts so the
|
|
47
|
+
* value reads as a duration on its own (a bare "45" needs a unit the
|
|
48
|
+
* surrounding sentence does not supply).
|
|
49
|
+
*
|
|
50
|
+
* Digits and a colon read the same in every locale this ships with, so the
|
|
51
|
+
* value can be interpolated into a translated sentence without each locale
|
|
52
|
+
* owning a time format.
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatOtpCountdown(secondsRemaining: number): string;
|
|
55
|
+
//# sourceMappingURL=otp-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otp-config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/otp-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,iBAAiB,CAAA;AAEhE,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,kBAAkB,EAAE,iBAGhC,CAAA;AA2BD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,IAAI,GAC1C,iBAAiB,CAcnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAmB,GACvB,MAAM,CAGR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAKnE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const DEFAULT_OTP_CONFIG = {
|
|
2
|
+
expiresIn: 60 * 5,
|
|
3
|
+
// 5 minutes
|
|
4
|
+
otpLength: 6
|
|
5
|
+
};
|
|
6
|
+
const MIN_OTP_LENGTH = 4;
|
|
7
|
+
const MAX_OTP_LENGTH = 10;
|
|
8
|
+
function isPositiveNumber(value) {
|
|
9
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
10
|
+
}
|
|
11
|
+
function resolveNumber(value, fallback, field) {
|
|
12
|
+
if (value === void 0) return fallback;
|
|
13
|
+
if (!isPositiveNumber(value) || Math.floor(value) < 1) {
|
|
14
|
+
console.warn(
|
|
15
|
+
`[Auth] Ignoring invalid auth.otp.${field} (${String(value)}); using default ${fallback}`
|
|
16
|
+
);
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
return Math.floor(value);
|
|
20
|
+
}
|
|
21
|
+
function resolveOtpConfig(authConfig) {
|
|
22
|
+
const cfg = (authConfig == null ? void 0 : authConfig.otp) ?? {};
|
|
23
|
+
const expiresIn = resolveNumber(cfg.expiresIn, DEFAULT_OTP_CONFIG.expiresIn, "expiresIn");
|
|
24
|
+
let otpLength = resolveNumber(cfg.otpLength, DEFAULT_OTP_CONFIG.otpLength, "otpLength");
|
|
25
|
+
if (otpLength < MIN_OTP_LENGTH || otpLength > MAX_OTP_LENGTH) {
|
|
26
|
+
console.warn(
|
|
27
|
+
`[Auth] auth.otp.otpLength (${otpLength}) is outside ${MIN_OTP_LENGTH}-${MAX_OTP_LENGTH}; using default ${DEFAULT_OTP_CONFIG.otpLength}`
|
|
28
|
+
);
|
|
29
|
+
otpLength = DEFAULT_OTP_CONFIG.otpLength;
|
|
30
|
+
}
|
|
31
|
+
return { expiresIn, otpLength };
|
|
32
|
+
}
|
|
33
|
+
function getOtpSecondsRemaining(sentAt, expiresIn, now = Date.now()) {
|
|
34
|
+
const elapsed = Math.floor((now - sentAt) / 1e3);
|
|
35
|
+
return Math.min(expiresIn, Math.max(0, expiresIn - elapsed));
|
|
36
|
+
}
|
|
37
|
+
function formatOtpCountdown(secondsRemaining) {
|
|
38
|
+
const total = Math.max(0, Math.floor(secondsRemaining));
|
|
39
|
+
const minutes = Math.floor(total / 60);
|
|
40
|
+
const seconds = total % 60;
|
|
41
|
+
return `${minutes}:${String(seconds).padStart(2, "0")}`;
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
DEFAULT_OTP_CONFIG,
|
|
45
|
+
formatOtpCountdown,
|
|
46
|
+
getOtpSecondsRemaining,
|
|
47
|
+
resolveOtpConfig
|
|
48
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/registration-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"registration-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/registration-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAIrF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAElE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAShF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAKnE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAKzE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAGT;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAa5E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveAuthMethods } from "./auth-methods.js";
|
|
2
|
+
import { resolveOtpConfig } from "./otp-config.js";
|
|
2
3
|
function isRegistrationOpen(mode) {
|
|
3
4
|
return mode === "open" || mode === "domain-open";
|
|
4
5
|
}
|
|
@@ -41,7 +42,8 @@ function getPublicAuthConfig(authConfig) {
|
|
|
41
42
|
enabled: isGoogleAuthEnabled(authConfig)
|
|
42
43
|
}
|
|
43
44
|
},
|
|
44
|
-
methods: resolveAuthMethods(authConfig)
|
|
45
|
+
methods: resolveAuthMethods(authConfig),
|
|
46
|
+
otp: resolveOtpConfig(authConfig)
|
|
45
47
|
};
|
|
46
48
|
}
|
|
47
49
|
export {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Hint
|
|
3
|
+
*
|
|
4
|
+
* Better Auth's session cookie is httpOnly, so client code cannot tell whether a
|
|
5
|
+
* visitor is signed in without asking the server. This readable cookie records
|
|
6
|
+
* whether the browser carries a session, and public pages ask for the session
|
|
7
|
+
* only when it says so: an anonymous visitor makes no session request. The proxy
|
|
8
|
+
* keeps it in line with the session cookie on every request, and client code
|
|
9
|
+
* updates it on sign-in, sign-out and each session it reads. It is a hint, never
|
|
10
|
+
* proof of anything: a stale one costs a single request that finds no session.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SESSION_HINT_COOKIE = "nextspark.signed_in";
|
|
13
|
+
/** As long as browsers keep a cookie: longer than any session. */
|
|
14
|
+
export declare const SESSION_HINT_MAX_AGE: number;
|
|
15
|
+
/**
|
|
16
|
+
* Whether a Cookie header carries Better Auth's session cookie. It says nothing
|
|
17
|
+
* about whether that session is still valid, only that there may be one to read.
|
|
18
|
+
*/
|
|
19
|
+
export declare function hasSessionCookie(cookieHeader: string | null | undefined): boolean;
|
|
20
|
+
/** Whether this browser was signed in when client code last looked. */
|
|
21
|
+
export declare function hasSessionHint(): boolean;
|
|
22
|
+
/** Record whether this browser is signed in. */
|
|
23
|
+
export declare function setSessionHint(signedIn: boolean): void;
|
|
24
|
+
/**
|
|
25
|
+
* Call `onChange` whenever the hint may have changed: client code set it (a
|
|
26
|
+
* sign-in or sign-out on this page), or the tab comes back into view, after
|
|
27
|
+
* responses the proxy answered may have set it. Returns the function that stops
|
|
28
|
+
* listening. Its shape fits React's useSyncExternalStore.
|
|
29
|
+
*/
|
|
30
|
+
export declare function subscribeSessionHint(onChange: () => void): () => void;
|
|
31
|
+
//# sourceMappingURL=session-hint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-hint.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/session-hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AAExD,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,QAAqB,CAAA;AAKtD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEjF;AAED,uEAAuE;AACvE,wBAAgB,cAAc,IAAI,OAAO,CAGxC;AAKD,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAOtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAUrE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const SESSION_HINT_COOKIE = "nextspark.signed_in";
|
|
2
|
+
const SESSION_HINT_MAX_AGE = 60 * 60 * 24 * 400;
|
|
3
|
+
const SESSION_COOKIE = /(?:^|;\s*)(?:__Secure-)?better-auth[.-]session_token=[^;\s]/;
|
|
4
|
+
function hasSessionCookie(cookieHeader) {
|
|
5
|
+
return SESSION_COOKIE.test(cookieHeader ?? "");
|
|
6
|
+
}
|
|
7
|
+
function hasSessionHint() {
|
|
8
|
+
if (typeof document === "undefined") return false;
|
|
9
|
+
return document.cookie.split(";").some((part) => part.trim() === `${SESSION_HINT_COOKIE}=1`);
|
|
10
|
+
}
|
|
11
|
+
const SESSION_HINT_CHANGE_EVENT = "nextspark:session-hint-change";
|
|
12
|
+
function setSessionHint(signedIn) {
|
|
13
|
+
if (typeof document === "undefined" || hasSessionHint() === signedIn) return;
|
|
14
|
+
const secure = typeof location !== "undefined" && location.protocol === "https:" ? "; Secure" : "";
|
|
15
|
+
document.cookie = signedIn ? `${SESSION_HINT_COOKIE}=1; Max-Age=${SESSION_HINT_MAX_AGE}; Path=/; SameSite=Lax${secure}` : `${SESSION_HINT_COOKIE}=; Max-Age=0; Path=/; SameSite=Lax${secure}`;
|
|
16
|
+
window.dispatchEvent(new Event(SESSION_HINT_CHANGE_EVENT));
|
|
17
|
+
}
|
|
18
|
+
function subscribeSessionHint(onChange) {
|
|
19
|
+
if (typeof window === "undefined") return () => {
|
|
20
|
+
};
|
|
21
|
+
window.addEventListener(SESSION_HINT_CHANGE_EVENT, onChange);
|
|
22
|
+
window.addEventListener("focus", onChange);
|
|
23
|
+
document.addEventListener("visibilitychange", onChange);
|
|
24
|
+
return () => {
|
|
25
|
+
window.removeEventListener(SESSION_HINT_CHANGE_EVENT, onChange);
|
|
26
|
+
window.removeEventListener("focus", onChange);
|
|
27
|
+
document.removeEventListener("visibilitychange", onChange);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
SESSION_HINT_COOKIE,
|
|
32
|
+
SESSION_HINT_MAX_AGE,
|
|
33
|
+
hasSessionCookie,
|
|
34
|
+
hasSessionHint,
|
|
35
|
+
setSessionHint,
|
|
36
|
+
subscribeSessionHint
|
|
37
|
+
};
|
package/dist/lib/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgF,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgF,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAgBvH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlF;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnF;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoHD,eAAO,MAAM,IAAI,qEAqWf,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,kBAAkB,EAAE,QAAQ,EAAE,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B"}
|
package/dist/lib/auth.js
CHANGED
|
@@ -16,6 +16,7 @@ import { shouldSkipTeamCreation, getSignupContext } from "./auth-context.js";
|
|
|
16
16
|
import { isDomainAllowed } from "./auth/registration-helpers.js";
|
|
17
17
|
import { registrationGuardPlugin } from "./auth/registration-guard-plugin.js";
|
|
18
18
|
import { resolveSessionConfig } from "./auth/session-config.js";
|
|
19
|
+
import { resolveOtpConfig } from "./auth/otp-config.js";
|
|
19
20
|
import { isPasswordLoginEnabled } from "./auth/auth-methods.js";
|
|
20
21
|
import { getCorsOrigins, isPrivateLanOrigin, normalizeCorsEnvironment } from "./utils/cors.js";
|
|
21
22
|
async function hasPendingInvitationForEmail(email) {
|
|
@@ -45,6 +46,7 @@ const pool = new Pool({
|
|
|
45
46
|
max: 20
|
|
46
47
|
});
|
|
47
48
|
const sessionConfig = resolveSessionConfig(AUTH_CONFIG);
|
|
49
|
+
const otpConfig = resolveOtpConfig(AUTH_CONFIG);
|
|
48
50
|
function resolveNonOwnerSignupRole() {
|
|
49
51
|
var _a, _b, _c, _d;
|
|
50
52
|
const cfg = AUTH_CONFIG.signupIntent;
|
|
@@ -220,13 +222,13 @@ const auth = betterAuth({
|
|
|
220
222
|
email,
|
|
221
223
|
otp,
|
|
222
224
|
type,
|
|
223
|
-
appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App"
|
|
225
|
+
appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App",
|
|
226
|
+
expiresIn: otpConfig.expiresIn
|
|
224
227
|
}, I18N_CONFIG.defaultLocale);
|
|
225
228
|
await emailService.send({ to: email, ...template });
|
|
226
229
|
},
|
|
227
|
-
otpLength:
|
|
228
|
-
expiresIn:
|
|
229
|
-
// 5 minutes
|
|
230
|
+
otpLength: otpConfig.otpLength,
|
|
231
|
+
expiresIn: otpConfig.expiresIn,
|
|
230
232
|
sendVerificationOnSignUp: false,
|
|
231
233
|
disableSignUp: false
|
|
232
234
|
// auto-create user on first OTP sign-in
|