@nextsparkjs/core 0.1.0-beta.187 → 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.d.ts +10 -1
- package/dist/components/dashboard/mobile/MobileTopBar.d.ts.map +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.js +4 -3
- 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/templates/proxy.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @nextspark-generated
|
|
3
|
+
*
|
|
4
|
+
* `nextspark sync:app` replaces this file while that tag is present, which is
|
|
5
|
+
* how a release ships changes to it. Delete the tag line to own the file: from
|
|
6
|
+
* then on sync reports it and leaves it alone.
|
|
7
|
+
*
|
|
2
8
|
* NextSpark Proxy (Next.js 16+)
|
|
3
9
|
*
|
|
4
10
|
* Handles authentication, route protection, and user context injection.
|
|
@@ -7,8 +13,8 @@
|
|
|
7
13
|
* Key responsibilities:
|
|
8
14
|
* 1. Theme middleware override support
|
|
9
15
|
* 2. Documentation access control
|
|
10
|
-
* 3. Protected route authentication
|
|
11
|
-
* 4. User header injection for downstream use (x-user-id, x-pathname)
|
|
16
|
+
* 3. Protected route authentication, and the roles /superadmin and /devtools need
|
|
17
|
+
* 4. User header injection for downstream use (x-user-id, x-pathname, x-active-team-id)
|
|
12
18
|
*
|
|
13
19
|
* IMPORTANT: The EntityPermissionLayout depends on x-user-id and x-pathname
|
|
14
20
|
* headers being set here for server-side permission validation.
|
|
@@ -20,6 +26,8 @@ import {
|
|
|
20
26
|
executeThemeMiddleware,
|
|
21
27
|
getThemeAppConfig
|
|
22
28
|
} from '@nextsparkjs/core/lib/middleware'
|
|
29
|
+
import { ACTIVE_TEAM_COOKIE, activeTeamIdForSession } from '@nextsparkjs/core/lib/teams/active-team-cookie'
|
|
30
|
+
import { SESSION_HINT_COOKIE, SESSION_HINT_MAX_AGE, hasSessionCookie } from '@nextsparkjs/core/lib/auth/session-hint'
|
|
23
31
|
|
|
24
32
|
/**
|
|
25
33
|
* Session type for proxy (inline definition)
|
|
@@ -64,6 +72,53 @@ function isPublicPath(pathname: string): boolean {
|
|
|
64
72
|
)
|
|
65
73
|
}
|
|
66
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Whether `pathname` is `prefix` or a path under it: `/devtools/config` is,
|
|
77
|
+
* `/devtools-guide` and `/profile-photo.jpg` are not.
|
|
78
|
+
*/
|
|
79
|
+
function isUnder(pathname: string, prefix: string): boolean {
|
|
80
|
+
return pathname === prefix || pathname.startsWith(`${prefix}/`)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A URL on this app at `pathname`, keeping the base path and locale the request
|
|
85
|
+
* came in with; one built from `request.url` would lose both.
|
|
86
|
+
*/
|
|
87
|
+
function appUrl(request: NextRequest, pathname: string): NextRequest['nextUrl'] {
|
|
88
|
+
const url = request.nextUrl.clone()
|
|
89
|
+
url.pathname = pathname
|
|
90
|
+
url.search = ''
|
|
91
|
+
return url
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Send a visitor without a session to login. LoginForm reads `callbackUrl` and
|
|
96
|
+
* returns them to the page they asked for, query included, once signed in.
|
|
97
|
+
*/
|
|
98
|
+
function redirectToLogin(request: NextRequest): NextResponse {
|
|
99
|
+
const loginUrl = appUrl(request, '/login')
|
|
100
|
+
loginUrl.searchParams.set('callbackUrl', `${request.nextUrl.pathname}${request.nextUrl.search}`)
|
|
101
|
+
return NextResponse.redirect(loginUrl)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Send a signed-in user without the role an area needs back to the dashboard. */
|
|
105
|
+
function redirectAccessDenied(request: NextRequest): NextResponse {
|
|
106
|
+
const dashboardUrl = appUrl(request, '/dashboard')
|
|
107
|
+
dashboardUrl.searchParams.set('error', 'access_denied')
|
|
108
|
+
return NextResponse.redirect(dashboardUrl)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The session the request's cookies carry, asked of this app's own auth route,
|
|
113
|
+
* which is served under the base path like every other route.
|
|
114
|
+
*/
|
|
115
|
+
function getSession(request: NextRequest) {
|
|
116
|
+
return betterFetch<Session>('/api/auth/get-session', {
|
|
117
|
+
baseURL: `${request.nextUrl.origin}${request.nextUrl.basePath}`,
|
|
118
|
+
headers: { cookie: request.headers.get('cookie') || '' },
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
67
122
|
/**
|
|
68
123
|
* Identity headers this proxy injects for downstream server code.
|
|
69
124
|
*
|
|
@@ -74,7 +129,7 @@ function isPublicPath(pathname: string): boolean {
|
|
|
74
129
|
* dispatches Server Actions by the `Next-Action` header, not by the URL, so an
|
|
75
130
|
* action can be POSTed to a public path with a forged `x-user-id`.
|
|
76
131
|
*/
|
|
77
|
-
const TRUSTED_IDENTITY_HEADERS = ['x-user-id', 'x-user-email', 'x-pathname'] as const
|
|
132
|
+
const TRUSTED_IDENTITY_HEADERS = ['x-user-id', 'x-user-email', 'x-pathname', 'x-active-team-id'] as const
|
|
78
133
|
|
|
79
134
|
/**
|
|
80
135
|
* Build the request headers forwarded to the app: inbound copy minus every
|
|
@@ -89,15 +144,38 @@ function sanitizeRequestHeaders(request: NextRequest): Headers {
|
|
|
89
144
|
return headers
|
|
90
145
|
}
|
|
91
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Keep the readable session hint (lib/auth/session-hint) in line with the
|
|
149
|
+
* session cookie, so client code knows whether to ask for the session. A browser
|
|
150
|
+
* that got its session without client code seeing it (before the hint existed,
|
|
151
|
+
* or through OAuth) gets the hint on its next request, and one whose session
|
|
152
|
+
* cookie is gone loses it. The session itself is not checked here.
|
|
153
|
+
*/
|
|
154
|
+
function syncSessionHint(request: NextRequest, response: NextResponse): NextResponse {
|
|
155
|
+
const hasSession = hasSessionCookie(request.headers.get('cookie'))
|
|
156
|
+
const hinted = request.cookies.get(SESSION_HINT_COOKIE)?.value === '1'
|
|
157
|
+
if (hasSession && !hinted) {
|
|
158
|
+
response.cookies.set(SESSION_HINT_COOKIE, '1', {
|
|
159
|
+
path: '/',
|
|
160
|
+
maxAge: SESSION_HINT_MAX_AGE,
|
|
161
|
+
sameSite: 'lax',
|
|
162
|
+
secure: request.nextUrl.protocol === 'https:',
|
|
163
|
+
})
|
|
164
|
+
} else if (!hasSession && hinted) {
|
|
165
|
+
response.cookies.set(SESSION_HINT_COOKIE, '', { path: '/', maxAge: 0 })
|
|
166
|
+
}
|
|
167
|
+
return response
|
|
168
|
+
}
|
|
169
|
+
|
|
92
170
|
/**
|
|
93
171
|
* Continue to the app with the (sanitized) request headers.
|
|
94
172
|
* Every pass-through in this proxy MUST go through here so the strip applies
|
|
95
173
|
* to public paths, /api/v1 and unmatched routes alike.
|
|
96
174
|
*/
|
|
97
|
-
function passThrough(requestHeaders: Headers): NextResponse {
|
|
98
|
-
return NextResponse.next({
|
|
175
|
+
function passThrough(request: NextRequest, requestHeaders: Headers): NextResponse {
|
|
176
|
+
return syncSessionHint(request, NextResponse.next({
|
|
99
177
|
request: { headers: requestHeaders },
|
|
100
|
-
})
|
|
178
|
+
}))
|
|
101
179
|
}
|
|
102
180
|
|
|
103
181
|
export async function proxy(request: NextRequest) {
|
|
@@ -129,76 +207,71 @@ export async function proxy(request: NextRequest) {
|
|
|
129
207
|
}
|
|
130
208
|
|
|
131
209
|
// 3. Documentation access control
|
|
132
|
-
if (pathname
|
|
210
|
+
if (isUnder(pathname, '/docs')) {
|
|
133
211
|
const appConfig = getThemeAppConfig(activeTheme as string)
|
|
134
212
|
|
|
135
213
|
if (appConfig?.docs?.public === false) {
|
|
136
214
|
try {
|
|
137
|
-
const { data: session } = await
|
|
138
|
-
'/api/auth/get-session',
|
|
139
|
-
{
|
|
140
|
-
baseURL: request.nextUrl.origin,
|
|
141
|
-
headers: { cookie: request.headers.get('cookie') || '' },
|
|
142
|
-
}
|
|
143
|
-
)
|
|
215
|
+
const { data: session } = await getSession(request)
|
|
144
216
|
|
|
145
217
|
if (!session) {
|
|
146
|
-
|
|
147
|
-
loginUrl.searchParams.set('redirect', pathname)
|
|
148
|
-
return NextResponse.redirect(loginUrl)
|
|
218
|
+
return redirectToLogin(request)
|
|
149
219
|
}
|
|
150
220
|
} catch (error) {
|
|
151
|
-
|
|
152
|
-
loginUrl.searchParams.set('redirect', pathname)
|
|
153
|
-
return NextResponse.redirect(loginUrl)
|
|
221
|
+
return redirectToLogin(request)
|
|
154
222
|
}
|
|
155
223
|
}
|
|
156
|
-
return passThrough(requestHeaders)
|
|
224
|
+
return passThrough(request, requestHeaders)
|
|
157
225
|
}
|
|
158
226
|
|
|
159
227
|
// 4. Allow public paths
|
|
160
228
|
if (isPublicPath(pathname)) {
|
|
161
|
-
return passThrough(requestHeaders)
|
|
229
|
+
return passThrough(request, requestHeaders)
|
|
162
230
|
}
|
|
163
231
|
|
|
164
232
|
// 5. API v1 routes handle their own dual authentication
|
|
165
233
|
if (pathname.startsWith('/api/v1')) {
|
|
166
|
-
return passThrough(requestHeaders)
|
|
234
|
+
return passThrough(request, requestHeaders)
|
|
167
235
|
}
|
|
168
236
|
|
|
169
|
-
// 6. Protected routes - require authentication and inject user headers
|
|
170
|
-
|
|
237
|
+
// 6. Protected routes - require authentication and inject user headers.
|
|
238
|
+
// Areas are matched by path segment, so /dashboard-guide is not /dashboard.
|
|
239
|
+
// /superadmin and /devtools also need a role, the same ones SuperAdminGuard
|
|
240
|
+
// and DeveloperGuard let in. The guards decide it again in the browser, but
|
|
241
|
+
// only after the page has been served, so it is decided here first.
|
|
242
|
+
const isAdminRoute = isUnder(pathname, '/admin')
|
|
243
|
+
const isSuperadminRoute = isUnder(pathname, '/superadmin')
|
|
244
|
+
const isDevtoolsRoute = isUnder(pathname, '/devtools')
|
|
171
245
|
const isProtectedRoute =
|
|
172
|
-
pathname
|
|
173
|
-
pathname
|
|
174
|
-
pathname
|
|
175
|
-
pathname
|
|
176
|
-
|
|
177
|
-
|
|
246
|
+
isUnder(pathname, '/dashboard') ||
|
|
247
|
+
isUnder(pathname, '/settings') ||
|
|
248
|
+
isUnder(pathname, '/profile') ||
|
|
249
|
+
isUnder(pathname, '/update-password') ||
|
|
250
|
+
isAdminRoute ||
|
|
251
|
+
isSuperadminRoute ||
|
|
252
|
+
isDevtoolsRoute
|
|
178
253
|
|
|
179
254
|
if (isProtectedRoute) {
|
|
180
255
|
try {
|
|
181
|
-
const { data: session } = await
|
|
182
|
-
'/api/auth/get-session',
|
|
183
|
-
{
|
|
184
|
-
baseURL: request.nextUrl.origin,
|
|
185
|
-
headers: { cookie: request.headers.get('cookie') || '' },
|
|
186
|
-
}
|
|
187
|
-
)
|
|
256
|
+
const { data: session } = await getSession(request)
|
|
188
257
|
|
|
189
258
|
if (!session) {
|
|
190
|
-
|
|
191
|
-
loginUrl.searchParams.set('callbackUrl', pathname)
|
|
192
|
-
return NextResponse.redirect(loginUrl)
|
|
259
|
+
return redirectToLogin(request)
|
|
193
260
|
}
|
|
194
261
|
|
|
262
|
+
const role = session.user?.role
|
|
263
|
+
|
|
195
264
|
// Admin Panel superadmin-only check
|
|
196
|
-
if (isAdminRoute) {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
265
|
+
if (isAdminRoute && role !== 'superadmin') {
|
|
266
|
+
return redirectAccessDenied(request)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (isSuperadminRoute && role !== 'superadmin' && role !== 'developer') {
|
|
270
|
+
return redirectAccessDenied(request)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (isDevtoolsRoute && role !== 'developer') {
|
|
274
|
+
return redirectAccessDenied(request)
|
|
202
275
|
}
|
|
203
276
|
|
|
204
277
|
// Inject user headers for downstream use, ONLY from the verified session
|
|
@@ -210,21 +283,33 @@ export async function proxy(request: NextRequest) {
|
|
|
210
283
|
if (session.user?.email) {
|
|
211
284
|
requestHeaders.set('x-user-email', session.user.email)
|
|
212
285
|
}
|
|
286
|
+
// The team this session chose, for the dashboard layouts' permission
|
|
287
|
+
// checks; a cookie another session left behind names no team here.
|
|
288
|
+
const activeTeamId = activeTeamIdForSession(request.cookies.get(ACTIVE_TEAM_COOKIE)?.value, session.session?.id)
|
|
289
|
+
if (activeTeamId) {
|
|
290
|
+
requestHeaders.set('x-active-team-id', activeTeamId)
|
|
291
|
+
}
|
|
213
292
|
|
|
214
|
-
return passThrough(requestHeaders)
|
|
293
|
+
return passThrough(request, requestHeaders)
|
|
215
294
|
} catch (error) {
|
|
216
295
|
console.error('Proxy error:', error)
|
|
217
|
-
|
|
218
|
-
loginUrl.searchParams.set('callbackUrl', pathname)
|
|
219
|
-
return NextResponse.redirect(loginUrl)
|
|
296
|
+
return redirectToLogin(request)
|
|
220
297
|
}
|
|
221
298
|
}
|
|
222
299
|
|
|
223
|
-
return passThrough(requestHeaders)
|
|
300
|
+
return passThrough(request, requestHeaders)
|
|
224
301
|
}
|
|
225
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Everything runs through the proxy except the exact paths of Next's own
|
|
305
|
+
* output: `_next/static/`, the `_next/image` endpoint and `favicon.ico`.
|
|
306
|
+
* Excluding by file extension, or by a prefix without its boundary, would let a
|
|
307
|
+
* dynamic segment such as `alice.png` or `favicon.icoevil` reach the app without
|
|
308
|
+
* the session check and with forged identity headers intact. Files under
|
|
309
|
+
* public/ simply pass through.
|
|
310
|
+
*/
|
|
226
311
|
export const config = {
|
|
227
312
|
matcher: [
|
|
228
|
-
'/((?!_next/static
|
|
313
|
+
'/((?!_next/static/|_next/image$|favicon\\.ico$).*)',
|
|
229
314
|
],
|
|
230
315
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/types/blocks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;;;iBAG/B,CAAA;AAEF,eAAO,MAAM,cAAc;;;mBAGzB,CAAA;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AACrD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAIpF;AAMD;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;;iBAIpB,CAAA;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;iBAI5B,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEhE;;;GAGG;AACH,eAAO,MAAM,sBAAsB,yIAWzB,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAErE;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;iBAE3B,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE9D;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAA;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../src/types/blocks.ts"],"names":[],"mappings":"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"}
|
package/dist/types/blocks.js
CHANGED
|
@@ -41,7 +41,7 @@ const baseAdvancedSchema = z.object({
|
|
|
41
41
|
className: z.string().optional(),
|
|
42
42
|
id: z.string().optional()
|
|
43
43
|
});
|
|
44
|
-
const baseBlockSchema = baseContentSchema.
|
|
44
|
+
const baseBlockSchema = baseContentSchema.extend(baseDesignSchema.shape).extend(baseAdvancedSchema.shape);
|
|
45
45
|
function getBackgroundClasses(backgroundColor) {
|
|
46
46
|
const bgMap = {
|
|
47
47
|
transparent: "bg-transparent",
|
|
@@ -56,6 +56,6 @@ export declare const TASK_PRIORITIES: Record<TaskPriority['level'], Omit<TaskPri
|
|
|
56
56
|
/**
|
|
57
57
|
* Available task categories
|
|
58
58
|
*/
|
|
59
|
-
export declare const TASK_CATEGORIES: readonly ["
|
|
59
|
+
export declare const TASK_CATEGORIES: readonly ["Design", "Development", "Meetings", "Documentation", "Testing", "General"];
|
|
60
60
|
export type TaskCategoryType = typeof TASK_CATEGORIES[number];
|
|
61
61
|
//# sourceMappingURL=task.types.d.ts.map
|
package/dist/types/task.types.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
const TASK_PRIORITIES = {
|
|
2
2
|
high: {
|
|
3
|
-
label: "
|
|
3
|
+
label: "High",
|
|
4
4
|
color: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"
|
|
5
5
|
},
|
|
6
6
|
medium: {
|
|
7
|
-
label: "
|
|
7
|
+
label: "Medium",
|
|
8
8
|
color: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200"
|
|
9
9
|
},
|
|
10
10
|
low: {
|
|
11
|
-
label: "
|
|
11
|
+
label: "Low",
|
|
12
12
|
color: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
const TASK_CATEGORIES = [
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
16
|
+
"Design",
|
|
17
|
+
"Development",
|
|
18
|
+
"Meetings",
|
|
19
|
+
"Documentation",
|
|
20
20
|
"Testing",
|
|
21
21
|
"General"
|
|
22
22
|
];
|
|
@@ -125,9 +125,9 @@ function TranslationDebugger() {
|
|
|
125
125
|
borderRadius: "4px",
|
|
126
126
|
fontSize: "10px"
|
|
127
127
|
}, children: [
|
|
128
|
-
"
|
|
128
|
+
tCommon("debug.hidePrefix"),
|
|
129
129
|
/* @__PURE__ */ jsx("code", { children: "?debug-i18n=true" }),
|
|
130
|
-
"
|
|
130
|
+
tCommon("debug.hideSuffix")
|
|
131
131
|
] })
|
|
132
132
|
]
|
|
133
133
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextsparkjs/core",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.189",
|
|
4
4
|
"description": "NextSpark - The complete SaaS framework for Next.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "NextSpark <hello@nextspark.dev>",
|
|
@@ -112,6 +112,10 @@
|
|
|
112
112
|
"types": "./dist/lib/scheduled-actions/handlers/index.d.ts",
|
|
113
113
|
"import": "./dist/lib/scheduled-actions/handlers/index.js"
|
|
114
114
|
},
|
|
115
|
+
"./lib/auth/*": {
|
|
116
|
+
"types": "./dist/lib/auth/*.d.ts",
|
|
117
|
+
"import": "./dist/lib/auth/*.js"
|
|
118
|
+
},
|
|
115
119
|
"./lib/auth/security-notifications": {
|
|
116
120
|
"types": "./dist/lib/auth/security-notifications/index.d.ts",
|
|
117
121
|
"import": "./dist/lib/auth/security-notifications/index.js"
|
|
@@ -392,6 +396,7 @@
|
|
|
392
396
|
"@types/pg": "^8.15.5",
|
|
393
397
|
"@types/react": "^19",
|
|
394
398
|
"@types/react-dom": "^19",
|
|
399
|
+
"@types/sanitize-html": "^2.16.1",
|
|
395
400
|
"allure-cypress": "^3.4.4",
|
|
396
401
|
"cypress": "^15.8.2",
|
|
397
402
|
"esbuild": "^0.27.3",
|
|
@@ -448,8 +453,6 @@
|
|
|
448
453
|
"@vercel/blob": "^2.0.0",
|
|
449
454
|
"better-auth": "~1.6.30",
|
|
450
455
|
"chalk": "^5.4.1",
|
|
451
|
-
"jiti": "^2.7.0",
|
|
452
|
-
"kysely": "0.28.17",
|
|
453
456
|
"class-variance-authority": "^0.7.1",
|
|
454
457
|
"clsx": "^2.1.1",
|
|
455
458
|
"cmdk": "^1.1.1",
|
|
@@ -457,6 +460,8 @@
|
|
|
457
460
|
"dotenv": "^17.2.2",
|
|
458
461
|
"fs-extra": "^11.2.0",
|
|
459
462
|
"gray-matter": "^4.0.3",
|
|
463
|
+
"jiti": "^2.7.0",
|
|
464
|
+
"kysely": "0.28.17",
|
|
460
465
|
"lucide-react": "^0.539.0",
|
|
461
466
|
"mermaid": "^11.0.0",
|
|
462
467
|
"next-intl": "^4.9.1",
|
|
@@ -472,6 +477,8 @@
|
|
|
472
477
|
"remark-gfm": "^4.0.1",
|
|
473
478
|
"remark-rehype": "^11.1.2",
|
|
474
479
|
"resend": "^5.0.0",
|
|
480
|
+
"sanitize-html": "^2.17.7",
|
|
481
|
+
"server-only": "^0.0.1",
|
|
475
482
|
"sharp": "^0.34.3 || ^0.35.3",
|
|
476
483
|
"shiki": "^3.20.0",
|
|
477
484
|
"sonner": "^2.0.7",
|
|
@@ -479,7 +486,7 @@
|
|
|
479
486
|
"tailwind-merge": "^3.3.1",
|
|
480
487
|
"uuid": "^13.0.0",
|
|
481
488
|
"zod": "^4.3.6",
|
|
482
|
-
"@nextsparkjs/testing": "0.1.0-beta.
|
|
489
|
+
"@nextsparkjs/testing": "0.1.0-beta.189"
|
|
483
490
|
},
|
|
484
491
|
"scripts": {
|
|
485
492
|
"postinstall": "node scripts/postinstall.mjs || true",
|
|
@@ -489,6 +496,8 @@
|
|
|
489
496
|
"dev": "tsup --watch",
|
|
490
497
|
"test": "jest",
|
|
491
498
|
"test:watch": "jest --watch",
|
|
492
|
-
"test:coverage": "jest --coverage"
|
|
499
|
+
"test:coverage": "jest --coverage",
|
|
500
|
+
"test:node": "npx tsx --test tests/node/*.test.ts",
|
|
501
|
+
"test:all": "pnpm test && pnpm test:node"
|
|
493
502
|
}
|
|
494
503
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the block-registry generators.
|
|
3
|
+
*
|
|
4
|
+
* What matters is which module carries which binding. block-registry.ts holds a
|
|
5
|
+
* static import of every block component, for server rendering, so whatever
|
|
6
|
+
* imports it bundles every block. Client components render blocks through
|
|
7
|
+
* block-registry.lazy.ts, which must not import a component statically, and read
|
|
8
|
+
* configs through block-registry.client.ts, which must not import one at all.
|
|
9
|
+
*
|
|
10
|
+
* Run: node --test packages/core/scripts/build/registry/__tests__/block-registry.test.mjs
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { test } from 'node:test'
|
|
14
|
+
import assert from 'node:assert/strict'
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
generateBlockRegistry,
|
|
18
|
+
generateBlockRegistryClient,
|
|
19
|
+
generateBlockRegistryLazy
|
|
20
|
+
} from '../generators/block-registry.mjs'
|
|
21
|
+
|
|
22
|
+
function block(slug, category) {
|
|
23
|
+
const base = `@/contents/themes/default/blocks/${slug}`
|
|
24
|
+
return {
|
|
25
|
+
slug,
|
|
26
|
+
name: slug,
|
|
27
|
+
description: `${slug} block`,
|
|
28
|
+
category,
|
|
29
|
+
icon: 'Box',
|
|
30
|
+
scope: ['pages'],
|
|
31
|
+
hasExamples: false,
|
|
32
|
+
themeName: 'default',
|
|
33
|
+
paths: {
|
|
34
|
+
component: `${base}/component`,
|
|
35
|
+
schema: `${base}/schema`,
|
|
36
|
+
fields: `${base}/fields`,
|
|
37
|
+
thumbnail: `/theme/blocks/${slug}/thumbnail.png`,
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const blocks = [block('hero', 'hero'), block('cta-section', 'cta')]
|
|
43
|
+
const config = { outputDir: '/tmp/registries', projectRoot: '/tmp/project' }
|
|
44
|
+
const staticComponentImport = /^import .* from '[^']*\/component'/m
|
|
45
|
+
|
|
46
|
+
test('the lazy registry loads each component on demand and imports none statically', () => {
|
|
47
|
+
const out = generateBlockRegistryLazy(blocks)
|
|
48
|
+
assert.doesNotMatch(out, staticComponentImport)
|
|
49
|
+
assert.match(out, /'hero': React\.lazy\(\(\) => import\('@\/contents\/themes\/default\/blocks\/hero\/component'\)/)
|
|
50
|
+
assert.match(out, /'cta-section': React\.lazy\(\(\) => import\('@\/contents\/themes\/default\/blocks\/cta-section\/component'\)/)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('the client registry imports no component', () => {
|
|
54
|
+
const out = generateBlockRegistryClient(blocks, config)
|
|
55
|
+
assert.doesNotMatch(out, staticComponentImport)
|
|
56
|
+
assert.doesNotMatch(out, /import\('[^']*\/component'\)/)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('the server registry imports components statically and re-exports the other halves', () => {
|
|
60
|
+
const out = generateBlockRegistry(blocks, config)
|
|
61
|
+
assert.match(out, staticComponentImport)
|
|
62
|
+
assert.match(out, /export \* from '\.\/block-registry\.client'/)
|
|
63
|
+
assert.match(out, /export \{ BLOCK_COMPONENTS \} from '\.\/block-registry\.lazy'/)
|
|
64
|
+
assert.doesNotMatch(out, /React\.lazy/)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('with no blocks, each half still exports what its importers expect', () => {
|
|
68
|
+
assert.match(generateBlockRegistryLazy([]), /export const BLOCK_COMPONENTS\b/)
|
|
69
|
+
assert.match(generateBlockRegistryClient([], config), /export const BLOCK_REGISTRY\b/)
|
|
70
|
+
const server = generateBlockRegistry([], config)
|
|
71
|
+
assert.match(server, /export \{ BLOCK_COMPONENTS \} from '\.\/block-registry\.lazy'/)
|
|
72
|
+
assert.match(server, /export const BLOCK_COMPONENTS_SSR\b/)
|
|
73
|
+
})
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for icon discovery.
|
|
3
|
+
*
|
|
4
|
+
* The two halves that can silently produce an empty or wrong registry — which
|
|
5
|
+
* degrades to every icon rendering as a Box, with no error anywhere — are the
|
|
6
|
+
* path matcher and the name extraction. Both are pure, so both are tested here
|
|
7
|
+
* directly; discoverIcons() itself only wires them to the filesystem.
|
|
8
|
+
*
|
|
9
|
+
* Run: node --test packages/core/scripts/build/registry/__tests__/icons-discovery.test.mjs
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { test } from 'node:test'
|
|
13
|
+
import assert from 'node:assert/strict'
|
|
14
|
+
|
|
15
|
+
import { findUnresolvedIconRefs, extractIconNames, isIconSourcePath } from '../discovery/icons.mjs'
|
|
16
|
+
|
|
17
|
+
test('matches entity, block and app configs', () => {
|
|
18
|
+
assert.ok(isIconSourcePath('/p/contents/themes/default/entities/tasks/tasks.config.ts'))
|
|
19
|
+
assert.ok(isIconSourcePath('/p/themes/default/blocks/hero/config.ts'))
|
|
20
|
+
assert.ok(isIconSourcePath('/p/themes/default/config/app.config.ts'))
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('matches the same paths with Windows separators', () => {
|
|
24
|
+
assert.ok(isIconSourcePath('C:\\p\\contents\\themes\\default\\entities\\tasks\\tasks.config.ts'))
|
|
25
|
+
assert.ok(isIconSourcePath('C:\\p\\themes\\default\\blocks\\hero\\config.ts'))
|
|
26
|
+
assert.ok(isIconSourcePath('C:\\p\\themes\\default\\config\\app.config.ts'))
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('ignores configs whose icons never reach resolveIcon', () => {
|
|
30
|
+
assert.equal(isIconSourcePath('/p/themes/crm/config/features.config.ts'), false)
|
|
31
|
+
assert.equal(isIconSourcePath('/p/themes/default/config/theme.config.ts'), false)
|
|
32
|
+
assert.equal(isIconSourcePath('/p/themes/default/entities/tasks/messages/en.ts'), false)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('does not match a file that merely ends in config.ts', () => {
|
|
36
|
+
assert.equal(isIconSourcePath('/p/themes/default/blocks/hero/notconfig.ts'), false)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('reads an icon under a quoted key', () => {
|
|
40
|
+
const source = `
|
|
41
|
+
import { Users } from 'lucide-react'
|
|
42
|
+
export const config = { 'icon': Users }
|
|
43
|
+
`
|
|
44
|
+
assert.deepEqual(extractIconNames(source), ['Users'])
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('reads an icon declared as a lucide import', () => {
|
|
48
|
+
const source = `
|
|
49
|
+
import { Users, CheckSquare } from 'lucide-react'
|
|
50
|
+
export const config = { icon: CheckSquare }
|
|
51
|
+
`
|
|
52
|
+
assert.deepEqual(extractIconNames(source), ['CheckSquare'])
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('resolves an aliased import back to the lucide export name', () => {
|
|
56
|
+
// `icon: HouseIcon` is lucide's `Home`; the registry is keyed by the export
|
|
57
|
+
const source = `
|
|
58
|
+
import { Home as HouseIcon } from 'lucide-react'
|
|
59
|
+
export const config = { icon: HouseIcon }
|
|
60
|
+
`
|
|
61
|
+
assert.deepEqual(extractIconNames(source), ['Home'])
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('ignores an identifier that did not come from lucide', () => {
|
|
65
|
+
const source = `
|
|
66
|
+
import { MyOwnIcon } from '@/components/icons'
|
|
67
|
+
export const config = { icon: MyOwnIcon }
|
|
68
|
+
`
|
|
69
|
+
assert.deepEqual(extractIconNames(source), [])
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('reads a string icon name, kebab-case included', () => {
|
|
73
|
+
const source = `export const config = { icon: 'pie-chart' }`
|
|
74
|
+
assert.deepEqual(extractIconNames(source), ['pie-chart'])
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test('does not match a different key that ends in icon', () => {
|
|
78
|
+
const source = `
|
|
79
|
+
import { Users } from 'lucide-react'
|
|
80
|
+
export const config = { sidebarIcon: Users, my_icon: Users }
|
|
81
|
+
`
|
|
82
|
+
assert.deepEqual(extractIconNames(source), [])
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('never yields anything but a bare name, so nothing can be injected', () => {
|
|
86
|
+
// The generated registry is TypeScript built from these strings, and every
|
|
87
|
+
// name becomes a named import. Whatever a config holds, what comes out here
|
|
88
|
+
// is a bare name — and discoverIcons then drops any that lucide doesn't
|
|
89
|
+
// export, which 'X' is.
|
|
90
|
+
const sources = [
|
|
91
|
+
`export const config = { icon: 'X"; process.exit(1); //' }`,
|
|
92
|
+
`export const config = { icon: 'Users } from "x"; import evil from "y"; //' }`,
|
|
93
|
+
'export const config = { icon: `${danger}` }'
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
for (const source of sources) {
|
|
97
|
+
for (const name of extractIconNames(source)) {
|
|
98
|
+
assert.match(name, /^[A-Za-z][\w$-]*$/, `unsafe name from: ${source}`)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// Only a direct lucide import or a string literal reaches the registry, so
|
|
104
|
+
// every other shape has to be reported rather than silently rendering a Box.
|
|
105
|
+
test('reports an icon reference the build cannot resolve', () => {
|
|
106
|
+
assert.deepEqual(
|
|
107
|
+
findUnresolvedIconRefs("import * as I from 'lucide-react'\nexport default { icon: I.Users }"),
|
|
108
|
+
['I.Users']
|
|
109
|
+
)
|
|
110
|
+
assert.deepEqual(
|
|
111
|
+
findUnresolvedIconRefs("import { Users } from './icons'\nexport default { icon: Users }"),
|
|
112
|
+
['Users']
|
|
113
|
+
)
|
|
114
|
+
assert.deepEqual(
|
|
115
|
+
findUnresolvedIconRefs("import { Users } from 'lucide-react'\nconst Mine = Users\nexport default { icon: Mine }"),
|
|
116
|
+
['Mine']
|
|
117
|
+
)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('says nothing about a reference it can resolve', () => {
|
|
121
|
+
assert.deepEqual(
|
|
122
|
+
findUnresolvedIconRefs("import { Users } from 'lucide-react'\nexport default { icon: Users }"),
|
|
123
|
+
[]
|
|
124
|
+
)
|
|
125
|
+
assert.deepEqual(
|
|
126
|
+
findUnresolvedIconRefs("import { Home as HouseIcon } from 'lucide-react'\nexport default { icon: HouseIcon }"),
|
|
127
|
+
[]
|
|
128
|
+
)
|
|
129
|
+
assert.deepEqual(findUnresolvedIconRefs("export default { icon: 'pie-chart' }"), [])
|
|
130
|
+
})
|