@nextsparkjs/core 0.1.0-beta.194 → 0.1.0-beta.196
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/app/guards/DeveloperGuard.d.ts +8 -1
- package/dist/components/app/guards/DeveloperGuard.d.ts.map +1 -1
- package/dist/components/app/guards/DeveloperGuard.js +2 -1
- package/dist/components/app/guards/SuperAdminGuard.d.ts +8 -1
- package/dist/components/app/guards/SuperAdminGuard.d.ts.map +1 -1
- package/dist/components/app/guards/SuperAdminGuard.js +2 -1
- package/dist/components/billing/InvoicesPagination.js +2 -2
- package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/block-picker.js +2 -1
- package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/builder-editor-view.js +39 -23
- package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
- package/dist/components/dashboard/layouts/AuthGuard.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/AuthGuard.js +3 -4
- package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.js +9 -10
- package/dist/components/dashboard/layouts/DashboardAuthLayout.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/DashboardAuthLayout.js +3 -4
- package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts +2 -2
- package/dist/components/dashboard/navigation/DynamicNavigation.js +2 -2
- package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
- package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -2
- package/dist/components/entities/wrappers/EntityFormWrapper.d.ts.map +1 -1
- package/dist/components/entities/wrappers/EntityFormWrapper.js +5 -2
- package/dist/components/entities/wrappers/EntityListWrapper.d.ts.map +1 -1
- package/dist/components/entities/wrappers/EntityListWrapper.js +5 -2
- package/dist/components/settings/layouts/SettingsSidebar.d.ts.map +1 -1
- package/dist/components/settings/layouts/SettingsSidebar.js +0 -1
- package/dist/components/teams/CreateTeamButton.js +2 -2
- package/dist/components/teams/CreateTeamDialog.js +1 -1
- package/dist/components/teams/InviteMemberButton.js +3 -3
- package/dist/components/teams/InviteMemberDialog.js +1 -1
- package/dist/components/teams/TeamPendingInvitations.js +2 -2
- package/dist/components/ui/relation-display.d.ts.map +1 -1
- package/dist/components/ui/relation-display.js +2 -1
- package/dist/components/ui/user-display.d.ts.map +1 -1
- package/dist/components/ui/user-display.js +2 -1
- package/dist/emails/otp-verification.d.ts.map +1 -1
- package/dist/emails/otp-verification.js +5 -3
- package/dist/emails/reset-password.d.ts.map +1 -1
- package/dist/emails/reset-password.js +5 -3
- package/dist/emails/team-invitation.d.ts.map +1 -1
- package/dist/emails/team-invitation.js +3 -2
- package/dist/emails/verify-email.d.ts.map +1 -1
- package/dist/emails/verify-email.js +5 -3
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +21 -4
- package/dist/hooks/usePatternUsages.d.ts.map +1 -1
- package/dist/hooks/usePatternUsages.js +3 -2
- package/dist/lib/api/api-error.d.ts +2 -0
- package/dist/lib/api/api-error.d.ts.map +1 -1
- package/dist/lib/api/api-error.js +3 -1
- package/dist/lib/api/auth/dual-auth.d.ts +2 -1
- package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
- package/dist/lib/api/auth/dual-auth.js +22 -4
- package/dist/lib/api/auth/scope-policy.d.ts +6 -3
- package/dist/lib/api/auth/scope-policy.d.ts.map +1 -1
- package/dist/lib/api/auth.d.ts +2 -0
- package/dist/lib/api/auth.d.ts.map +1 -1
- package/dist/lib/api/auth.js +10 -10
- package/dist/lib/api/client-headers.d.ts +11 -0
- package/dist/lib/api/client-headers.d.ts.map +1 -0
- package/dist/lib/api/client-headers.js +12 -0
- package/dist/lib/api/client-ip.d.ts +59 -0
- package/dist/lib/api/client-ip.d.ts.map +1 -0
- package/dist/lib/api/client-ip.js +91 -0
- package/dist/lib/api/cors-response.d.ts +55 -0
- package/dist/lib/api/cors-response.d.ts.map +1 -0
- package/dist/lib/api/cors-response.js +90 -0
- package/dist/lib/api/entities.d.ts.map +1 -1
- package/dist/lib/api/entities.js +4 -3
- package/dist/lib/api/entity/audit-log.d.ts.map +1 -1
- package/dist/lib/api/entity/audit-log.js +2 -1
- package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
- package/dist/lib/api/entity/generic-handler.js +23 -8
- package/dist/lib/api/helpers.d.ts +8 -2
- package/dist/lib/api/helpers.d.ts.map +1 -1
- package/dist/lib/api/helpers.js +32 -103
- package/dist/lib/api/keys.d.ts +6 -0
- package/dist/lib/api/keys.d.ts.map +1 -1
- package/dist/lib/api/keys.js +7 -1
- package/dist/lib/api/permission-middleware.d.ts.map +1 -1
- package/dist/lib/api/permission-middleware.js +0 -2
- package/dist/lib/api/rate-limit.d.ts +12 -0
- package/dist/lib/api/rate-limit.d.ts.map +1 -1
- package/dist/lib/api/rate-limit.js +50 -43
- package/dist/lib/api/request-origin.d.ts +16 -7
- package/dist/lib/api/request-origin.d.ts.map +1 -1
- package/dist/lib/api/request-origin.js +43 -20
- package/dist/lib/auth/load-login-page.d.ts +10 -0
- package/dist/lib/auth/load-login-page.d.ts.map +1 -0
- package/dist/lib/auth/load-login-page.js +7 -0
- package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
- package/dist/lib/auth/runtime-readiness.js +4 -0
- package/dist/lib/auth/sample-accounts.d.ts +17 -0
- package/dist/lib/auth/sample-accounts.d.ts.map +1 -0
- package/dist/lib/auth/sample-accounts.js +22 -0
- package/dist/lib/auth/security-notifications/device-fingerprint.d.ts +1 -8
- package/dist/lib/auth/security-notifications/device-fingerprint.d.ts.map +1 -1
- package/dist/lib/auth/security-notifications/device-fingerprint.js +2 -12
- package/dist/lib/auth-email-callbacks.js +3 -3
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +13 -5
- package/dist/lib/cache/public-entity-cache.d.ts +21 -0
- package/dist/lib/cache/public-entity-cache.d.ts.map +1 -0
- package/dist/lib/cache/public-entity-cache.js +25 -0
- package/dist/lib/config/config-client.d.ts.map +1 -1
- package/dist/lib/config/config-client.js +1 -1
- package/dist/lib/config/config-sync.d.ts.map +1 -1
- package/dist/lib/config/config-sync.js +1 -1
- package/dist/lib/config/public-config-client.d.ts +1 -0
- package/dist/lib/config/public-config-client.d.ts.map +1 -1
- package/dist/lib/config/public-config-client.js +3 -1
- package/dist/lib/config/types.d.ts +2 -0
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/constants/reserved-slugs.d.ts +17 -8
- package/dist/lib/constants/reserved-slugs.d.ts.map +1 -1
- package/dist/lib/constants/reserved-slugs.js +16 -52
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +9 -3
- package/dist/lib/entities/entity-hooks.d.ts.map +1 -1
- package/dist/lib/entities/entity-hooks.js +4 -0
- package/dist/lib/entities/external-api-generator.d.ts.map +1 -1
- package/dist/lib/entities/external-api-generator.js +2 -4
- package/dist/lib/entities/public-slug.d.ts +46 -0
- package/dist/lib/entities/public-slug.d.ts.map +1 -0
- package/dist/lib/entities/public-slug.js +39 -0
- package/dist/lib/mcp/errors.d.ts +2 -0
- package/dist/lib/mcp/errors.d.ts.map +1 -1
- package/dist/lib/mcp/errors.js +3 -1
- package/dist/lib/mcp/index.d.ts +1 -1
- package/dist/lib/mcp/index.d.ts.map +1 -1
- package/dist/lib/mcp/index.js +2 -1
- package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
- package/dist/lib/services/generic-entity.service.js +2 -0
- package/dist/lib/teams/actions.d.ts.map +1 -1
- package/dist/lib/teams/actions.js +0 -1
- package/dist/messages/de/billing.json +12 -1
- package/dist/messages/de/common.json +2 -0
- package/dist/messages/de/docs.json +1 -0
- package/dist/messages/de/features.json +16 -4
- package/dist/messages/de/home.json +5 -0
- package/dist/messages/de/index.d.ts +68 -25
- package/dist/messages/de/index.d.ts.map +1 -1
- package/dist/messages/de/index.js +2 -0
- package/dist/messages/de/index.ts +2 -0
- package/dist/messages/de/settings.json +1 -0
- package/dist/messages/de/teams.json +3 -18
- package/dist/messages/en/billing.json +1 -1
- package/dist/messages/en/common.json +2 -0
- package/dist/messages/en/docs.json +1 -0
- package/dist/messages/en/features.json +16 -4
- package/dist/messages/en/home.json +5 -0
- package/dist/messages/en/index.d.ts +58 -25
- package/dist/messages/en/index.d.ts.map +1 -1
- package/dist/messages/en/index.js +2 -0
- package/dist/messages/en/index.ts +2 -0
- package/dist/messages/en/settings.json +1 -0
- package/dist/messages/en/teams.json +3 -18
- package/dist/messages/es/billing.json +1 -1
- package/dist/messages/es/common.json +2 -0
- package/dist/messages/es/docs.json +1 -0
- package/dist/messages/es/features.json +16 -4
- package/dist/messages/es/home.json +5 -0
- package/dist/messages/es/index.d.ts +41 -8
- package/dist/messages/es/index.d.ts.map +1 -1
- package/dist/messages/es/index.js +2 -0
- package/dist/messages/es/index.ts +2 -0
- package/dist/messages/es/settings.json +1 -0
- package/dist/messages/es/teams.json +3 -0
- package/dist/messages/fr/billing.json +12 -1
- package/dist/messages/fr/common.json +2 -0
- package/dist/messages/fr/docs.json +1 -0
- package/dist/messages/fr/features.json +16 -4
- package/dist/messages/fr/home.json +5 -0
- package/dist/messages/fr/index.d.ts +68 -25
- package/dist/messages/fr/index.d.ts.map +1 -1
- package/dist/messages/fr/index.js +2 -0
- package/dist/messages/fr/index.ts +2 -0
- package/dist/messages/fr/settings.json +1 -0
- package/dist/messages/fr/teams.json +3 -18
- package/dist/messages/it/billing.json +12 -1
- package/dist/messages/it/common.json +2 -0
- package/dist/messages/it/docs.json +1 -0
- package/dist/messages/it/features.json +16 -4
- package/dist/messages/it/home.json +5 -0
- package/dist/messages/it/index.d.ts +68 -25
- package/dist/messages/it/index.d.ts.map +1 -1
- package/dist/messages/it/index.js +2 -0
- package/dist/messages/it/index.ts +2 -0
- package/dist/messages/it/settings.json +1 -0
- package/dist/messages/it/teams.json +3 -18
- package/dist/messages/pt/billing.json +12 -1
- package/dist/messages/pt/common.json +2 -0
- package/dist/messages/pt/docs.json +1 -0
- package/dist/messages/pt/features.json +16 -4
- package/dist/messages/pt/home.json +5 -0
- package/dist/messages/pt/index.d.ts +68 -25
- package/dist/messages/pt/index.d.ts.map +1 -1
- package/dist/messages/pt/index.js +2 -0
- package/dist/messages/pt/index.ts +2 -0
- package/dist/messages/pt/settings.json +1 -0
- package/dist/messages/pt/teams.json +3 -18
- package/dist/migrations/029_sample_accounts_outside_development.sql +55 -0
- package/dist/migrations/090_sample_data.sql +10 -0
- package/dist/routes/(auth)/signup/page.cc.d.ts +3 -8
- package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
- package/dist/routes/(auth)/signup/page.cc.js +7 -1
- package/dist/routes/(auth)/verify-email/page.d.ts.map +1 -1
- package/dist/routes/(auth)/verify-email/page.js +2 -1
- package/dist/routes/(public)/page.cc.d.ts +3 -0
- package/dist/routes/(public)/page.cc.d.ts.map +1 -0
- package/dist/routes/(public)/page.cc.js +3 -0
- package/dist/routes/_internal/area-access.cc.d.ts +21 -0
- package/dist/routes/_internal/area-access.cc.d.ts.map +1 -0
- package/dist/routes/_internal/area-access.cc.js +19 -0
- package/dist/routes/_internal/auth-layout.d.ts.map +1 -1
- package/dist/routes/_internal/auth-layout.js +3 -2
- package/dist/routes/_internal/dashboard-main-shared.d.ts +7 -0
- package/dist/routes/_internal/dashboard-main-shared.d.ts.map +1 -0
- package/dist/routes/_internal/dashboard-main-shared.js +49 -0
- package/dist/routes/_internal/default-auth-layout.d.ts.map +1 -1
- package/dist/routes/_internal/default-auth-layout.js +3 -2
- package/dist/routes/_internal/devtools-layout.cc.d.ts +3 -2
- package/dist/routes/_internal/devtools-layout.cc.d.ts.map +1 -1
- package/dist/routes/_internal/devtools-layout.cc.js +1 -1
- package/dist/routes/_internal/devtools-layout.d.ts +7 -2
- package/dist/routes/_internal/devtools-layout.d.ts.map +1 -1
- package/dist/routes/_internal/devtools-layout.js +4 -4
- package/dist/routes/_internal/entity-detail-route.cc.d.ts +8 -0
- package/dist/routes/_internal/entity-detail-route.cc.d.ts.map +1 -0
- package/dist/routes/_internal/entity-detail-route.cc.js +5 -0
- package/dist/routes/_internal/entity-edit-route.cc.d.ts +8 -0
- package/dist/routes/_internal/entity-edit-route.cc.d.ts.map +1 -0
- package/dist/routes/_internal/entity-edit-route.cc.js +5 -0
- package/dist/routes/_internal/entity-permission-layout.d.ts.map +1 -1
- package/dist/routes/_internal/entity-permission-layout.js +0 -7
- package/dist/routes/_internal/public-archive-route.d.ts +1 -1
- package/dist/routes/_internal/public-archive-route.d.ts.map +1 -1
- package/dist/routes/_internal/public-archive-route.js +8 -3
- package/dist/routes/_internal/public-item-route.cc.d.ts +5 -1
- package/dist/routes/_internal/public-item-route.cc.d.ts.map +1 -1
- package/dist/routes/_internal/public-item-route.cc.js +2 -1
- package/dist/routes/_internal/public-item-route.d.ts +7 -0
- package/dist/routes/_internal/public-item-route.d.ts.map +1 -1
- package/dist/routes/_internal/public-item-route.js +6 -1
- package/dist/routes/_internal/superadmin-layout.cc.d.ts +2 -1
- package/dist/routes/_internal/superadmin-layout.cc.d.ts.map +1 -1
- package/dist/routes/_internal/superadmin-layout.cc.js +1 -1
- package/dist/routes/_internal/superadmin-layout.d.ts +7 -2
- package/dist/routes/_internal/superadmin-layout.d.ts.map +1 -1
- package/dist/routes/_internal/superadmin-layout.js +6 -6
- package/dist/routes/_internal/suspended-route.d.ts +16 -0
- package/dist/routes/_internal/suspended-route.d.ts.map +1 -0
- package/dist/routes/_internal/suspended-route.js +7 -0
- package/dist/routes/api/auth/[...all]/route.d.ts.map +1 -1
- package/dist/routes/api/auth/[...all]/route.js +4 -12
- package/dist/routes/api/csp-report/route.d.ts.map +1 -1
- package/dist/routes/api/csp-report/route.js +2 -13
- package/dist/routes/api/devtools/config/entities/route.d.ts +2 -0
- package/dist/routes/api/devtools/config/entities/route.d.ts.map +1 -1
- package/dist/routes/api/devtools/config/entities/route.js +2 -0
- package/dist/routes/api/devtools/config/theme/route.d.ts +2 -0
- package/dist/routes/api/devtools/config/theme/route.d.ts.map +1 -1
- package/dist/routes/api/devtools/config/theme/route.js +2 -0
- package/dist/routes/api/devtools/tests/[...path]/route.d.ts +2 -0
- package/dist/routes/api/devtools/tests/[...path]/route.d.ts.map +1 -1
- package/dist/routes/api/devtools/tests/[...path]/route.js +2 -0
- package/dist/routes/api/devtools/tests/route.d.ts +2 -0
- package/dist/routes/api/devtools/tests/route.d.ts.map +1 -1
- package/dist/routes/api/devtools/tests/route.js +2 -0
- package/dist/routes/api/health/route.d.ts +2 -0
- package/dist/routes/api/health/route.d.ts.map +1 -1
- package/dist/routes/api/health/route.js +2 -0
- package/dist/routes/api/internal/user-metadata/route.d.ts +2 -0
- package/dist/routes/api/internal/user-metadata/route.d.ts.map +1 -1
- package/dist/routes/api/internal/user-metadata/route.js +2 -0
- package/dist/routes/api/mcp/route.d.ts +2 -0
- package/dist/routes/api/mcp/route.d.ts.map +1 -1
- package/dist/routes/api/mcp/route.js +9 -1
- package/dist/routes/api/superadmin/subscriptions/route.d.ts +2 -0
- package/dist/routes/api/superadmin/subscriptions/route.d.ts.map +1 -1
- package/dist/routes/api/superadmin/subscriptions/route.js +2 -0
- package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts +2 -0
- package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts.map +1 -1
- package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -0
- package/dist/routes/api/superadmin/teams/route.d.ts +2 -0
- package/dist/routes/api/superadmin/teams/route.d.ts.map +1 -1
- package/dist/routes/api/superadmin/teams/route.js +2 -0
- package/dist/routes/api/superadmin/users/[userId]/route.d.ts +2 -0
- package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
- package/dist/routes/api/superadmin/users/[userId]/route.js +2 -0
- package/dist/routes/api/superadmin/users/route.d.ts +2 -0
- package/dist/routes/api/superadmin/users/route.d.ts.map +1 -1
- package/dist/routes/api/superadmin/users/route.js +2 -0
- package/dist/routes/api/user/delete-account/route.d.ts +2 -0
- package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
- package/dist/routes/api/user/delete-account/route.js +2 -0
- package/dist/routes/api/user/plan-flags/route.d.ts +2 -0
- package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
- package/dist/routes/api/user/plan-flags/route.js +2 -0
- package/dist/routes/api/user/profile/route.d.ts +2 -0
- package/dist/routes/api/user/profile/route.d.ts.map +1 -1
- package/dist/routes/api/user/profile/route.js +4 -3
- package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts +2 -0
- package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.js +2 -0
- package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts +2 -0
- package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.js +2 -0
- package/dist/routes/api/v1/billing/cancel/route.d.ts +2 -0
- package/dist/routes/api/v1/billing/cancel/route.d.ts.map +1 -1
- package/dist/routes/api/v1/billing/cancel/route.js +2 -0
- package/dist/routes/api/v1/billing/change-plan/route.d.ts +2 -0
- package/dist/routes/api/v1/billing/change-plan/route.d.ts.map +1 -1
- package/dist/routes/api/v1/billing/change-plan/route.js +2 -0
- package/dist/routes/api/v1/billing/check-action/route.d.ts +2 -0
- package/dist/routes/api/v1/billing/check-action/route.d.ts.map +1 -1
- package/dist/routes/api/v1/billing/check-action/route.js +2 -0
- package/dist/routes/api/v1/billing/checkout/route.d.ts +2 -0
- package/dist/routes/api/v1/billing/checkout/route.d.ts.map +1 -1
- package/dist/routes/api/v1/billing/checkout/route.js +2 -0
- package/dist/routes/api/v1/billing/plans/route.d.ts +2 -0
- package/dist/routes/api/v1/billing/plans/route.d.ts.map +1 -1
- package/dist/routes/api/v1/billing/plans/route.js +2 -0
- package/dist/routes/api/v1/billing/portal/route.d.ts +2 -0
- package/dist/routes/api/v1/billing/portal/route.d.ts.map +1 -1
- package/dist/routes/api/v1/billing/portal/route.js +2 -0
- package/dist/routes/api/v1/blocks/[slug]/route.d.ts +2 -0
- package/dist/routes/api/v1/blocks/[slug]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/blocks/[slug]/route.js +2 -0
- package/dist/routes/api/v1/blocks/route.d.ts +2 -0
- package/dist/routes/api/v1/blocks/route.d.ts.map +1 -1
- package/dist/routes/api/v1/blocks/route.js +2 -0
- package/dist/routes/api/v1/blocks/validate/route.d.ts +2 -0
- package/dist/routes/api/v1/blocks/validate/route.d.ts.map +1 -1
- package/dist/routes/api/v1/blocks/validate/route.js +2 -0
- package/dist/routes/api/v1/devtools/blocks/route.d.ts +2 -1
- package/dist/routes/api/v1/devtools/blocks/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/blocks/route.js +2 -9
- package/dist/routes/api/v1/devtools/docs/route.d.ts +2 -0
- package/dist/routes/api/v1/devtools/docs/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/docs/route.js +2 -0
- package/dist/routes/api/v1/devtools/features/route.d.ts +2 -1
- package/dist/routes/api/v1/devtools/features/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/features/route.js +2 -9
- package/dist/routes/api/v1/devtools/flows/route.d.ts +2 -1
- package/dist/routes/api/v1/devtools/flows/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/flows/route.js +2 -9
- package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts +2 -1
- package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/scheduled-actions/route.js +2 -9
- package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts +2 -1
- package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/scheduled-actions/run/route.js +2 -9
- package/dist/routes/api/v1/devtools/testing/route.d.ts +2 -1
- package/dist/routes/api/v1/devtools/testing/route.d.ts.map +1 -1
- package/dist/routes/api/v1/devtools/testing/route.js +2 -9
- package/dist/routes/api/v1/media/[id]/route.d.ts +2 -0
- package/dist/routes/api/v1/media/[id]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/[id]/route.js +2 -0
- package/dist/routes/api/v1/media/[id]/tags/route.d.ts +2 -0
- package/dist/routes/api/v1/media/[id]/tags/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/[id]/tags/route.js +2 -0
- package/dist/routes/api/v1/media/check-duplicates/route.d.ts +2 -0
- package/dist/routes/api/v1/media/check-duplicates/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/check-duplicates/route.js +2 -0
- package/dist/routes/api/v1/media/route.d.ts +2 -0
- package/dist/routes/api/v1/media/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/route.js +2 -0
- package/dist/routes/api/v1/media/upload/route.d.ts +4 -1
- package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/upload/route.js +12 -2
- package/dist/routes/api/v1/media-tags/route.d.ts +2 -0
- package/dist/routes/api/v1/media-tags/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media-tags/route.js +2 -0
- package/dist/routes/api/v1/post-categories/[id]/route.d.ts +2 -0
- package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/post-categories/[id]/route.js +2 -0
- package/dist/routes/api/v1/post-categories/route.d.ts +2 -0
- package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
- package/dist/routes/api/v1/post-categories/route.js +2 -0
- package/dist/routes/api/v1/teams/[teamId]/members/route.d.ts.map +1 -1
- package/dist/routes/api/v1/teams/[teamId]/members/route.js +14 -12
- package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts +2 -0
- package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts.map +1 -1
- package/dist/routes/api/v1/teams/[teamId]/subscription/route.js +2 -0
- package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts +2 -0
- package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.js +2 -0
- package/dist/routes/api/v1/teams/switch/route.d.ts.map +1 -1
- package/dist/routes/api/v1/teams/switch/route.js +4 -1
- package/dist/routes/api/v1/users/[id]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/users/[id]/route.js +3 -2
- package/dist/routes/api/v1/users/docs.md +34 -19
- package/dist/routes/api/v1/users/me/route.d.ts +6 -0
- package/dist/routes/api/v1/users/me/route.d.ts.map +1 -0
- package/dist/routes/api/v1/users/me/route.js +5 -0
- package/dist/routes/api/v1/users/presets.ts +2 -2
- package/dist/routes/dashboard/(main)/layout.cc.d.ts +4 -0
- package/dist/routes/dashboard/(main)/layout.cc.d.ts.map +1 -0
- package/dist/routes/dashboard/(main)/layout.cc.js +10 -0
- package/dist/routes/dashboard/(main)/layout.d.ts.map +1 -1
- package/dist/routes/dashboard/(main)/layout.js +3 -44
- package/dist/routes/dashboard/permission-denied/page.d.ts +1 -1
- package/dist/routes/dashboard/permission-denied/page.d.ts.map +1 -1
- package/dist/routes/dashboard/permission-denied/page.js +5 -1
- package/dist/routes/dashboard/settings/password/page.d.ts.map +1 -1
- package/dist/routes/dashboard/settings/password/page.js +10 -12
- package/dist/routes/devtools/config/page.js +1 -1
- package/dist/routes/devtools/layout.cc.d.ts.map +1 -1
- package/dist/routes/devtools/layout.cc.js +5 -1
- package/dist/routes/devtools/page.js +1 -1
- package/dist/routes/devtools/scheduled-actions/page.js +1 -1
- package/dist/routes/devtools/tests/[[...path]]/page.js +1 -1
- package/dist/routes/manifest.json +10 -0
- package/dist/routes/robots.d.ts +10 -0
- package/dist/routes/robots.d.ts.map +1 -0
- package/dist/routes/robots.js +10 -0
- package/dist/routes/superadmin/layout.cc.d.ts.map +1 -1
- package/dist/routes/superadmin/layout.cc.js +5 -1
- package/dist/routes/variants.json +12 -2
- package/dist/templates/ci-workflows/github/cypress-regression.yml +1 -1
- package/dist/templates/ci-workflows/github/cypress-smoke.yml +2 -1
- package/dist/templates/next.config.mjs +2 -29
- package/dist/templates/projects/blog/api/authors/[username]/route.ts +3 -0
- package/dist/templates/projects/blog/api/authors/route.ts +3 -0
- package/dist/templates/projects/blog/api/posts/public/route.ts +3 -0
- package/dist/templates/projects/starter/README.md +2 -0
- package/dist/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
- package/dist/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
- package/dist/templates/proxy.ts +27 -9
- package/dist/templates/public/favicon.ico +0 -0
- package/dist/templates/public/uploads/README.md +5 -94
- package/migrations/029_sample_accounts_outside_development.sql +55 -0
- package/migrations/090_sample_data.sql +10 -0
- package/package.json +2 -2
- package/scripts/build/registry/__tests__/api-docs-colocated.test.mjs +3 -0
- package/scripts/build/registry/__tests__/billing-registry.test.mjs +50 -1
- package/scripts/build/registry/__tests__/block-registry.test.mjs +3 -0
- package/scripts/build/registry/__tests__/icons-discovery.test.mjs +3 -0
- package/scripts/build/registry/__tests__/quiet-console.mjs +17 -0
- package/scripts/build/registry/__tests__/safe-fs.test.mjs +3 -0
- package/scripts/build/registry/__tests__/team-roles.test.mjs +3 -0
- package/scripts/build/registry/discovery/permissions.test.mjs +3 -0
- package/scripts/build/registry/discovery/plugin-capabilities.mjs +2 -2
- package/scripts/build/registry/generators/billing-registry.mjs +7 -3
- package/scripts/build/registry/host/README.md +25 -1
- package/scripts/build/registry/host/__tests__/host-area-access.test.mjs +32 -0
- package/scripts/build/registry/host/__tests__/host-entities.test.mjs +32 -1
- package/scripts/build/registry/host/__tests__/host-plan.test.mjs +12 -2
- package/scripts/build/registry/host/__tests__/host-proxy-areas.test.mjs +72 -1
- package/scripts/build/registry/host/entity-routes.mjs +9 -3
- package/scripts/build/registry/host/proxy-areas.mjs +65 -2
- package/scripts/build/registry/host/static-imports.mjs +4 -0
- package/scripts/build/routes-manifest.mjs +13 -1
- package/scripts/db/run-migrations.mjs +30 -10
- package/scripts/db/sample-data.mjs +44 -0
- package/scripts/db/ssl-config.mjs +12 -1
- package/scripts/db/verify-theme-migrations.mjs +6 -0
- package/templates/ci-workflows/github/cypress-regression.yml +1 -1
- package/templates/ci-workflows/github/cypress-smoke.yml +2 -1
- package/templates/next.config.mjs +2 -29
- package/templates/projects/blog/api/authors/[username]/route.ts +3 -0
- package/templates/projects/blog/api/authors/route.ts +3 -0
- package/templates/projects/blog/api/posts/public/route.ts +3 -0
- package/templates/projects/starter/README.md +2 -0
- package/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
- package/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
- package/templates/proxy.ts +27 -9
- package/templates/public/favicon.ico +0 -0
- package/templates/public/uploads/README.md +5 -94
- package/tests/jest/__mocks__/@nextsparkjs/registries/api-presets-registry.ts +2 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/mcp-registry.ts +2 -0
- package/dist/templates/projects/starter/public/brand/.gitkeep +0 -0
- package/dist/templates/public/uploads/.gitignore +0 -6
- package/dist/templates/public/uploads/temp/.gitkeep +0 -1
- package/templates/projects/starter/public/brand/.gitkeep +0 -0
- package/templates/public/uploads/.gitignore +0 -6
- package/templates/public/uploads/temp/.gitkeep +0 -1
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
CheckCircle,
|
|
10
10
|
Loader2
|
|
11
11
|
} from "lucide-react";
|
|
12
|
-
import { useState, useCallback } from "react";
|
|
12
|
+
import { useState, useCallback, useEffect } from "react";
|
|
13
13
|
import { useForm } from "react-hook-form";
|
|
14
14
|
import { useRouter } from "next/navigation";
|
|
15
15
|
import { Button } from "@nextsparkjs/core/components/ui/button";
|
|
@@ -25,6 +25,7 @@ function UpdatePasswordPage() {
|
|
|
25
25
|
const { hasPassword, isLoading: profileLoading } = useUserProfile();
|
|
26
26
|
const router = useRouter();
|
|
27
27
|
const t = useTranslations("settings");
|
|
28
|
+
const tCommon = useTranslations("common");
|
|
28
29
|
const [loading, setLoading] = useState(false);
|
|
29
30
|
const [error, setError] = useState(null);
|
|
30
31
|
const [success, setSuccess] = useState(false);
|
|
@@ -58,7 +59,7 @@ function UpdatePasswordPage() {
|
|
|
58
59
|
if (!result.success) {
|
|
59
60
|
const errorMsg = result.error || t("password.messages.updateError");
|
|
60
61
|
setError(errorMsg);
|
|
61
|
-
setStatusMessage(`${
|
|
62
|
+
setStatusMessage(`${tCommon("status.error")}: ${errorMsg}`);
|
|
62
63
|
} else {
|
|
63
64
|
setSuccess(true);
|
|
64
65
|
setStatusMessage(t("password.messages.updateSuccess"));
|
|
@@ -66,25 +67,22 @@ function UpdatePasswordPage() {
|
|
|
66
67
|
} catch {
|
|
67
68
|
const errorMsg = t("password.messages.unexpectedError");
|
|
68
69
|
setError(errorMsg);
|
|
69
|
-
setStatusMessage(`${
|
|
70
|
+
setStatusMessage(`${tCommon("status.error")}: ${errorMsg}`);
|
|
70
71
|
} finally {
|
|
71
72
|
setLoading(false);
|
|
72
73
|
}
|
|
73
|
-
}, [changePassword, t]);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
if (!profileLoading && !hasPassword) {
|
|
79
|
-
router.push("/dashboard/settings/profile");
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
74
|
+
}, [changePassword, t, tCommon]);
|
|
75
|
+
const mustRedirectToProfile = !!user && !profileLoading && !hasPassword;
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (mustRedirectToProfile) router.push("/dashboard/settings/profile");
|
|
78
|
+
}, [mustRedirectToProfile, router]);
|
|
82
79
|
if (profileLoading) {
|
|
83
80
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-12", children: [
|
|
84
81
|
/* @__PURE__ */ jsx(Loader2, { className: "h-8 w-8 animate-spin text-muted-foreground" }),
|
|
85
82
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("password.loading.verifying") })
|
|
86
83
|
] });
|
|
87
84
|
}
|
|
85
|
+
if (!user || mustRedirectToProfile) return null;
|
|
88
86
|
if (success) {
|
|
89
87
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
90
88
|
/* @__PURE__ */ jsx(
|
|
@@ -4,7 +4,7 @@ import { ConfigViewer } from "@nextsparkjs/core/components/devtools/ConfigViewer
|
|
|
4
4
|
import { Settings } from "lucide-react";
|
|
5
5
|
import { getTranslations } from "next-intl/server";
|
|
6
6
|
async function DevConfigPageContent() {
|
|
7
|
-
const t = await getTranslations("
|
|
7
|
+
const t = await getTranslations("devtools.config");
|
|
8
8
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", "data-cy": "devtools-config-page", children: [
|
|
9
9
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
10
10
|
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center w-12 h-12 bg-violet-100 dark:bg-violet-950 rounded-lg", children: /* @__PURE__ */ jsx(Settings, { className: "h-6 w-6 text-violet-600 dark:text-violet-400" }) }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.cc.d.ts","sourceRoot":"","sources":["../../../src/routes/devtools/layout.cc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAIpC,eAAO,MAAM,QAAQ,EAAE,QAA0B,CAAA;;;;
|
|
1
|
+
{"version":3,"file":"layout.cc.d.ts","sourceRoot":"","sources":["../../../src/routes/devtools/layout.cc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAIpC,eAAO,MAAM,QAAQ,EAAE,QAA0B,CAAA;;;;AAUjD,wBAA+D"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
1
2
|
import { DevLayout, defaultMetadata } from "../_internal/devtools-layout.js";
|
|
2
3
|
import { withDevtoolsAreaMessages } from "../_internal/devtools-layout.cc.js";
|
|
3
4
|
export const metadata = defaultMetadata;
|
|
4
|
-
|
|
5
|
+
function ServerCheckedDevLayout({ children }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(DevLayout, { serverChecked: true, children });
|
|
7
|
+
}
|
|
8
|
+
export default withDevtoolsAreaMessages(ServerCheckedDevLayout);
|
|
@@ -5,7 +5,7 @@ import Link from "next/link";
|
|
|
5
5
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@nextsparkjs/core/components/ui/card";
|
|
6
6
|
import { getTranslations } from "next-intl/server";
|
|
7
7
|
async function DevHomePageContent() {
|
|
8
|
-
const t = await getTranslations("
|
|
8
|
+
const t = await getTranslations("devtools");
|
|
9
9
|
const tCommon = await getTranslations("common");
|
|
10
10
|
const sections = [
|
|
11
11
|
{
|
|
@@ -26,7 +26,7 @@ async function fetchScheduledActions(filters, page, limit) {
|
|
|
26
26
|
return response.json();
|
|
27
27
|
}
|
|
28
28
|
export default function ScheduledActionsPage() {
|
|
29
|
-
const t = useTranslations("
|
|
29
|
+
const t = useTranslations("devtools.scheduledActions");
|
|
30
30
|
const [filters, setFilters] = useState({});
|
|
31
31
|
const [page, setPage] = useState(1);
|
|
32
32
|
const limit = 20;
|
|
@@ -5,7 +5,7 @@ import { FileText } from "lucide-react";
|
|
|
5
5
|
import { getTranslations } from "next-intl/server";
|
|
6
6
|
async function DevTestsPageContent({ params }) {
|
|
7
7
|
const { path } = await params;
|
|
8
|
-
const t = await getTranslations("
|
|
8
|
+
const t = await getTranslations("devtools.tests");
|
|
9
9
|
const initialPath = (path == null ? void 0 : path.join("/")) || null;
|
|
10
10
|
return /* @__PURE__ */ jsxs(
|
|
11
11
|
"div",
|
|
@@ -422,6 +422,11 @@
|
|
|
422
422
|
"target": "api/v1/users/[id]/route.ts",
|
|
423
423
|
"specifier": "@nextsparkjs/core/routes/api/v1/users/[id]/route"
|
|
424
424
|
},
|
|
425
|
+
{
|
|
426
|
+
"kind": "route",
|
|
427
|
+
"target": "api/v1/users/me/route.ts",
|
|
428
|
+
"specifier": "@nextsparkjs/core/routes/api/v1/users/me/route"
|
|
429
|
+
},
|
|
425
430
|
{
|
|
426
431
|
"kind": "route",
|
|
427
432
|
"target": "api/v1/users/route.ts",
|
|
@@ -716,6 +721,11 @@
|
|
|
716
721
|
"target": "public/page.tsx",
|
|
717
722
|
"specifier": "@nextsparkjs/core/routes/public/page"
|
|
718
723
|
},
|
|
724
|
+
{
|
|
725
|
+
"kind": "robots",
|
|
726
|
+
"target": "robots.ts",
|
|
727
|
+
"specifier": "@nextsparkjs/core/routes/robots"
|
|
728
|
+
},
|
|
719
729
|
{
|
|
720
730
|
"kind": "page",
|
|
721
731
|
"target": "superadmin/docs/[section]/[page]/page.tsx",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MetadataRoute } from 'next';
|
|
2
|
+
/**
|
|
3
|
+
* /robots.txt (#214): public pages are crawlable, the authenticated areas and the API are not.
|
|
4
|
+
*
|
|
5
|
+
* Answers `text/plain` 200 in Cache Components and legacy ISR alike, so a crawler never gets the public
|
|
6
|
+
* catch-all page's HTML. A project overrides it with its own `robots.ts` (templates/robots.ts), which
|
|
7
|
+
* replaces this route. Core has no sitemap, so none is declared.
|
|
8
|
+
*/
|
|
9
|
+
export default function robots(): MetadataRoute.Robots;
|
|
10
|
+
//# sourceMappingURL=robots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../src/routes/robots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAGzC;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,IAAI,aAAa,CAAC,MAAM,CAQrD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { withBasePath } from "@nextsparkjs/core/lib/base-path";
|
|
2
|
+
export default function robots() {
|
|
3
|
+
return {
|
|
4
|
+
rules: {
|
|
5
|
+
userAgent: "*",
|
|
6
|
+
allow: withBasePath("/"),
|
|
7
|
+
disallow: ["/dashboard", "/superadmin", "/devtools", "/api"].map(withBasePath)
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.cc.d.ts","sourceRoot":"","sources":["../../../src/routes/superadmin/layout.cc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAIpC,eAAO,MAAM,QAAQ,EAAE,QAA0B,CAAA;;;;
|
|
1
|
+
{"version":3,"file":"layout.cc.d.ts","sourceRoot":"","sources":["../../../src/routes/superadmin/layout.cc.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAIpC,eAAO,MAAM,QAAQ,EAAE,QAA0B,CAAA;;;;AAUjD,wBAAwE"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
1
2
|
import { SuperadminLayout, defaultMetadata } from "../_internal/superadmin-layout.js";
|
|
2
3
|
import { withSuperadminAreaMessages } from "../_internal/superadmin-layout.cc.js";
|
|
3
4
|
export const metadata = defaultMetadata;
|
|
4
|
-
|
|
5
|
+
function ServerCheckedSuperadminLayout({ children }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(SuperadminLayout, { serverChecked: true, children });
|
|
7
|
+
}
|
|
8
|
+
export default withSuperadminAreaMessages(ServerCheckedSuperadminLayout);
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"wrapper": "withSuperadminAccess",
|
|
40
40
|
"metadata": "withSuperadminMetadata",
|
|
41
41
|
"handler": "withSuperadminRouteAccess",
|
|
42
|
-
"specifier": "@nextsparkjs/core/routes/_internal/area-access"
|
|
42
|
+
"specifier": "@nextsparkjs/core/routes/_internal/area-access.cc"
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"wrapper": "withDevtoolsAccess",
|
|
55
55
|
"metadata": "withDevtoolsMetadata",
|
|
56
56
|
"handler": "withDevtoolsRouteAccess",
|
|
57
|
-
"specifier": "@nextsparkjs/core/routes/_internal/area-access"
|
|
57
|
+
"specifier": "@nextsparkjs/core/routes/_internal/area-access.cc"
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
{
|
|
@@ -62,6 +62,16 @@
|
|
|
62
62
|
"target": "dashboard/layout.tsx",
|
|
63
63
|
"specifier": "@nextsparkjs/core/routes/dashboard/layout.cc"
|
|
64
64
|
},
|
|
65
|
+
{
|
|
66
|
+
"kind": "layout",
|
|
67
|
+
"target": "dashboard/(main)/layout.tsx",
|
|
68
|
+
"specifier": "@nextsparkjs/core/routes/dashboard/(main)/layout.cc"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"kind": "page",
|
|
72
|
+
"target": "(public)/page.tsx",
|
|
73
|
+
"specifier": "@nextsparkjs/core/routes/(public)/page.cc"
|
|
74
|
+
},
|
|
65
75
|
{
|
|
66
76
|
"kind": "page",
|
|
67
77
|
"target": "(auth)/login/page.tsx",
|
|
@@ -59,7 +59,8 @@ jobs:
|
|
|
59
59
|
- name: Setup database
|
|
60
60
|
env:
|
|
61
61
|
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
|
|
62
|
-
|
|
62
|
+
# a throwaway test database: migrations plus the sample users the tests sign in as
|
|
63
|
+
run: pnpm db:seed
|
|
63
64
|
|
|
64
65
|
- name: Build application
|
|
65
66
|
run: pnpm build
|
|
@@ -260,35 +260,8 @@ const nextConfig = {
|
|
|
260
260
|
source: '/:path*',
|
|
261
261
|
headers: securityHeaders
|
|
262
262
|
},
|
|
263
|
-
// CORS headers
|
|
264
|
-
//
|
|
265
|
-
// to support multiple origins (web app, mobile app, etc.)
|
|
266
|
-
// In production, we set static CORS headers here
|
|
267
|
-
...(isProduction ? [{
|
|
268
|
-
source: '/api/:path*',
|
|
269
|
-
headers: [
|
|
270
|
-
{
|
|
271
|
-
key: 'Access-Control-Allow-Origin',
|
|
272
|
-
value: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
key: 'Access-Control-Allow-Methods',
|
|
276
|
-
value: 'GET, POST, PUT, DELETE, OPTIONS, PATCH'
|
|
277
|
-
},
|
|
278
|
-
{
|
|
279
|
-
key: 'Access-Control-Allow-Headers',
|
|
280
|
-
value: 'Content-Type, Authorization, x-api-key, x-verify-from-ui, Cookie, Set-Cookie'
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
key: 'Access-Control-Allow-Credentials',
|
|
284
|
-
value: 'true'
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
key: 'Access-Control-Expose-Headers',
|
|
288
|
-
value: 'Set-Cookie'
|
|
289
|
-
}
|
|
290
|
-
]
|
|
291
|
-
}] : [])
|
|
263
|
+
// No CORS headers here: core's API routes answer CORS per request (addCorsHeaders), so the
|
|
264
|
+
// origins in api.cors.allowedOrigins and CORS_ADDITIONAL_ORIGINS get their grant in production too
|
|
292
265
|
]
|
|
293
266
|
},
|
|
294
267
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { NextRequest, NextResponse } from 'next/server'
|
|
11
11
|
import { queryWithRLS } from '@nextsparkjs/core/lib/db'
|
|
12
12
|
import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
|
|
13
|
+
import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response'
|
|
13
14
|
|
|
14
15
|
interface Author {
|
|
15
16
|
id: string
|
|
@@ -151,3 +152,5 @@ const getHandler = async (
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
export const GET = withRateLimitTier(getHandler, 'read')
|
|
155
|
+
|
|
156
|
+
export const OPTIONS = corsPreflight
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { NextRequest, NextResponse } from 'next/server'
|
|
11
11
|
import { queryWithRLS } from '@nextsparkjs/core/lib/db'
|
|
12
12
|
import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
|
|
13
|
+
import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response'
|
|
13
14
|
|
|
14
15
|
interface AuthorWithCount {
|
|
15
16
|
id: string
|
|
@@ -64,3 +65,5 @@ const getHandler = async (request: NextRequest) => {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
export const GET = withRateLimitTier(getHandler, 'read')
|
|
68
|
+
|
|
69
|
+
export const OPTIONS = corsPreflight
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { NextRequest, NextResponse } from 'next/server'
|
|
12
12
|
import { queryWithRLS } from '@nextsparkjs/core/lib/db'
|
|
13
13
|
import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
|
|
14
|
+
import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response'
|
|
14
15
|
|
|
15
16
|
interface Post {
|
|
16
17
|
id: string
|
|
@@ -152,3 +153,5 @@ const getHandler = async (request: NextRequest) => {
|
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
export const GET = withRateLimitTier(getHandler, 'read')
|
|
156
|
+
|
|
157
|
+
export const OPTIONS = corsPreflight
|
|
@@ -17,6 +17,8 @@ Welcome to the Starter theme for NextSpark. This minimal theme provides everythi
|
|
|
17
17
|
3. Run migrations: `pnpm db:migrate`
|
|
18
18
|
4. Start development: `pnpm dev`
|
|
19
19
|
|
|
20
|
+
Sample users (DevKeyring, Cypress) are for local development only: `pnpm db:seed` loads them; `pnpm db:migrate` alone does not, and neither applies them when `NODE_ENV` is `production`.
|
|
21
|
+
|
|
20
22
|
## Project Structure
|
|
21
23
|
|
|
22
24
|
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NextIntlClientProvider } from 'next-intl'
|
|
2
|
+
import { getMessages } from 'next-intl/server'
|
|
3
|
+
import { selectMessages } from '@nextsparkjs/core/lib/i18n/client-messages'
|
|
4
|
+
|
|
5
|
+
// TasksChart and RecentActivity are client components that read the `analytics`
|
|
6
|
+
// namespace, which the dashboard group does not carry to the browser by default.
|
|
7
|
+
export default async function AnalyticsLayout({ children }: { children: React.ReactNode }) {
|
|
8
|
+
const messages = await getMessages()
|
|
9
|
+
return (
|
|
10
|
+
<NextIntlClientProvider messages={selectMessages(messages, 'dashboard', ['analytics'])}>
|
|
11
|
+
{children}
|
|
12
|
+
</NextIntlClientProvider>
|
|
13
|
+
)
|
|
14
|
+
}
|
package/dist/templates/proxy.ts
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
* themselves and use only x-pathname from here, as a routing hint; the
|
|
21
21
|
* identity headers are still stripped and re-set for project code.
|
|
22
22
|
*/
|
|
23
|
-
import { betterFetch } from '@better-fetch/fetch'
|
|
24
23
|
import { NextRequest, NextResponse } from 'next/server'
|
|
24
|
+
import { auth } from '@nextsparkjs/core/lib/auth'
|
|
25
25
|
import {
|
|
26
26
|
hasProjectMiddleware,
|
|
27
27
|
executeProjectMiddleware,
|
|
@@ -181,14 +181,22 @@ function redirectAccessDenied(request: NextRequest): NextResponse {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
/**
|
|
184
|
-
* The session the request's cookies carry,
|
|
185
|
-
*
|
|
184
|
+
* The session the request's cookies carry, read in this process the way core's
|
|
185
|
+
* server code reads it. Asking the app's own /api/auth/get-session over HTTP
|
|
186
|
+
* built the URL from the request's origin, which behind a proxy that
|
|
187
|
+
* terminates TLS (X-Forwarded-Proto: https) is https on a port that speaks
|
|
188
|
+
* plain HTTP: the fetch failed and every signed-in user was sent to /login.
|
|
189
|
+
* Nothing here leaves the process, so no forwarded scheme or host can point
|
|
190
|
+
* the check anywhere. `disableRefresh`: this response cannot carry the renewed
|
|
191
|
+
* session cookie, so the rolling renewal is left to the auth route
|
|
192
|
+
* (lib/auth/session-refresh).
|
|
186
193
|
*/
|
|
187
|
-
function getSession(request: NextRequest) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
194
|
+
async function getSession(request: NextRequest): Promise<Session | null> {
|
|
195
|
+
const session = await auth.api.getSession({
|
|
196
|
+
headers: new Headers({ cookie: request.headers.get('cookie') || '' }),
|
|
197
|
+
query: { disableRefresh: true },
|
|
191
198
|
})
|
|
199
|
+
return session as Session | null
|
|
192
200
|
}
|
|
193
201
|
|
|
194
202
|
/**
|
|
@@ -200,8 +208,19 @@ function getSession(request: NextRequest) {
|
|
|
200
208
|
* session. Gating the strip on protected prefixes is not enough: Next.js
|
|
201
209
|
* dispatches Server Actions by the `Next-Action` header, not by the URL, so an
|
|
202
210
|
* action can be POSTed to a public path with a forged `x-user-id`.
|
|
211
|
+
*
|
|
212
|
+
* The `x-api-*` names are never set here: core takes an API key's identity from
|
|
213
|
+
* validating the key, and nothing downstream may receive them from the client.
|
|
203
214
|
*/
|
|
204
|
-
const TRUSTED_IDENTITY_HEADERS = [
|
|
215
|
+
const TRUSTED_IDENTITY_HEADERS = [
|
|
216
|
+
'x-user-id',
|
|
217
|
+
'x-user-email',
|
|
218
|
+
'x-pathname',
|
|
219
|
+
'x-active-team-id',
|
|
220
|
+
'x-api-user-id',
|
|
221
|
+
'x-api-key-id',
|
|
222
|
+
'x-api-scopes',
|
|
223
|
+
] as const
|
|
205
224
|
|
|
206
225
|
/**
|
|
207
226
|
* Build the request headers forwarded to the app: inbound copy minus every
|
|
@@ -479,7 +498,6 @@ export async function proxy(request: NextRequest) {
|
|
|
479
498
|
const verifiedSession = async (): Promise<Session | null> => {
|
|
480
499
|
if (!sessionPromise) {
|
|
481
500
|
sessionPromise = getSession(request)
|
|
482
|
-
.then(({ data }) => data)
|
|
483
501
|
.catch(error => {
|
|
484
502
|
sessionError = error
|
|
485
503
|
return null
|
|
Binary file
|
|
@@ -1,97 +1,8 @@
|
|
|
1
|
-
# Media
|
|
1
|
+
# Media uploads
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
This application uses **Vercel Blob Storage** for all media uploads. Files are stored in the cloud, not on the local filesystem.
|
|
3
|
+
`POST /api/v1/media/upload` stores files in **Vercel Blob** when `BLOB_READ_WRITE_TOKEN` is set. The media library lists the Blob URLs.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
- **Development without a token:** files are written to `public/uploads/temp/` (git-ignored) so the library works offline.
|
|
6
|
+
- **Production without a token:** the upload answers `503` with code `STORAGE_NOT_CONFIGURED`. Nothing is written to disk: a file under `public/` is not served until the next restart and does not survive a redeploy.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
**POST** `/api/v1/media/upload`
|
|
10
|
-
|
|
11
|
-
### Authentication
|
|
12
|
-
Requires valid user session (Better Auth)
|
|
13
|
-
|
|
14
|
-
### Request
|
|
15
|
-
- **Content-Type**: `multipart/form-data`
|
|
16
|
-
- **Field name**: `files` (accepts multiple files)
|
|
17
|
-
|
|
18
|
-
### Supported File Types
|
|
19
|
-
- Images: JPEG, PNG, GIF, WebP
|
|
20
|
-
- Videos: MP4, MPEG, QuickTime, WebM
|
|
21
|
-
|
|
22
|
-
### File Size Limit
|
|
23
|
-
- Maximum: 10MB per file
|
|
24
|
-
|
|
25
|
-
### Response
|
|
26
|
-
```json
|
|
27
|
-
{
|
|
28
|
-
"message": "Files uploaded successfully",
|
|
29
|
-
"urls": [
|
|
30
|
-
"https://xxxxx.public.blob.vercel-storage.com/uploads/temp/1234567890_abc123.jpg",
|
|
31
|
-
"https://xxxxx.public.blob.vercel-storage.com/uploads/temp/1234567890_def456.png"
|
|
32
|
-
],
|
|
33
|
-
"count": 2
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## File Naming Convention
|
|
38
|
-
Files are automatically renamed using the pattern:
|
|
39
|
-
```
|
|
40
|
-
{timestamp}_{randomString}.{extension}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Example: `1704067200000_k9x2m4p.jpg`
|
|
44
|
-
|
|
45
|
-
## Storage Location
|
|
46
|
-
- **Storage Provider**: Vercel Blob (cloud object storage)
|
|
47
|
-
- **Blob Path**: `uploads/temp/{filename}` (organizational prefix, not a filesystem path)
|
|
48
|
-
- **Public URL**: `https://xxxxx.public.blob.vercel-storage.com/uploads/temp/{filename}`
|
|
49
|
-
|
|
50
|
-
### How It Works
|
|
51
|
-
|
|
52
|
-
**Local Development:**
|
|
53
|
-
- Files are uploaded directly to Vercel Blob using `BLOB_READ_WRITE_TOKEN` from `.env`
|
|
54
|
-
- No files are saved to your local filesystem
|
|
55
|
-
- URLs point to Vercel's CDN
|
|
56
|
-
|
|
57
|
-
**Production/Staging:**
|
|
58
|
-
- Same behavior - files go directly to Vercel Blob
|
|
59
|
-
- Uses environment-specific Blob token
|
|
60
|
-
- No filesystem writes (Vercel serverless is read-only)
|
|
61
|
-
|
|
62
|
-
## Usage in AI Content Generation
|
|
63
|
-
The generate-content endpoint (`/api/content-buddy/generate-content`) automatically processes images for AI analysis.
|
|
64
|
-
|
|
65
|
-
**Supported URL formats:**
|
|
66
|
-
- Vercel Blob URLs: `https://xxxxx.public.blob.vercel-storage.com/uploads/temp/image.jpg`
|
|
67
|
-
- External URLs: `https://example.com/image.jpg` (also supported)
|
|
68
|
-
|
|
69
|
-
## Configuration
|
|
70
|
-
Requires `BLOB_READ_WRITE_TOKEN` environment variable:
|
|
71
|
-
|
|
72
|
-
```env
|
|
73
|
-
BLOB_READ_WRITE_TOKEN="vercel_blob_rw_..."
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Cleanup
|
|
77
|
-
Files are managed through Vercel Blob's retention policies.
|
|
78
|
-
|
|
79
|
-
**Manual cleanup** (if needed):
|
|
80
|
-
```typescript
|
|
81
|
-
import { del } from '@vercel/blob'
|
|
82
|
-
|
|
83
|
-
// Delete specific file
|
|
84
|
-
await del(fileUrl)
|
|
85
|
-
|
|
86
|
-
// Or list and delete old files
|
|
87
|
-
import { list } from '@vercel/blob'
|
|
88
|
-
const { blobs } = await list({ prefix: 'uploads/temp/' })
|
|
89
|
-
// Filter and delete as needed
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Security Notes
|
|
93
|
-
- All uploads require authentication
|
|
94
|
-
- File type validation prevents malicious uploads
|
|
95
|
-
- File size limits prevent DoS attacks
|
|
96
|
-
- Random filenames prevent enumeration attacks
|
|
97
|
-
- Files stored in secure Vercel Blob infrastructure
|
|
8
|
+
Self-hosting needs a storage provider: set `BLOB_READ_WRITE_TOKEN` (a Vercel Blob token, starts with `vercel_blob_`). See the media library docs.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- Migration: 029_sample_accounts_outside_development.sql
|
|
2
|
+
-- Description: sample accounts keep no usable credentials outside development
|
|
3
|
+
--
|
|
4
|
+
-- Sample data (090_sample_data.sql and the projects' *sample_data* files) is
|
|
5
|
+
-- only applied by an explicit development opt-in (`nextspark db:seed`,
|
|
6
|
+
-- `--sample-data` or NEXTSPARK_SEED_SAMPLE_DATA=1). Databases migrated before
|
|
7
|
+
-- that may still hold the sample accounts. This migration finds them by the
|
|
8
|
+
-- sample password, never by name, so a renamed account is found and an account
|
|
9
|
+
-- whose password was changed is left alone; for each one it:
|
|
10
|
+
-- - removes the sample password (its "credential" account row),
|
|
11
|
+
-- - removes its sessions,
|
|
12
|
+
-- - deactivates its API keys (status 'inactive'; deleting them would delete
|
|
13
|
+
-- their api_audit_log rows),
|
|
14
|
+
-- - sets its global role to 'member' (027's trigger then removes it from the
|
|
15
|
+
-- System Admin Team, as for any user who loses that role).
|
|
16
|
+
-- It also removes the sample sessions and deactivates the sample API key by
|
|
17
|
+
-- their fixed values, whoever owns them now. Nothing else is changed.
|
|
18
|
+
--
|
|
19
|
+
-- It runs once, everywhere, except in a development run that opted into sample
|
|
20
|
+
-- data (the runner sets nextspark.seed_sample_data to 'on' then), where those
|
|
21
|
+
-- accounts are wanted. To keep using one of them deliberately, give it a new
|
|
22
|
+
-- password before upgrading; to restore one afterwards, set its role back and
|
|
23
|
+
-- reset its password.
|
|
24
|
+
|
|
25
|
+
DO $$
|
|
26
|
+
DECLARE
|
|
27
|
+
sample_passwords CONSTANT TEXT[] := ARRAY[
|
|
28
|
+
'22de14d5472248ed0bece911df908b2a:d29576424798ba6845d348a3767c0b0f38a00f2aca461b3b1d34b99a93cab06c86774c6edb183e6d6ec47457649b032a49a7b60a48f6f4f7fbbc4ea40258f19f',
|
|
29
|
+
'3db9e98e2b4d3caca97fdf2783791cbc:34b293de615caf277a237773208858e960ea8aa10f1f5c5c309b632f192cac34d52ceafbd338385616f4929e4b1b6c055b67429c6722ffdb80b01d9bf4764866'
|
|
30
|
+
];
|
|
31
|
+
sample_session_tokens CONSTANT TEXT[] := ARRAY['tmt_superadmin_session_token_001', 'tmt_developer_session_token_001'];
|
|
32
|
+
sample_key_hashes CONSTANT TEXT[] := ARRAY[
|
|
33
|
+
'205f13ae4d2e18df417e61123bb84030c124fcb5013699046379ae1b5ec04324',
|
|
34
|
+
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
35
|
+
];
|
|
36
|
+
sample_users TEXT[];
|
|
37
|
+
BEGIN
|
|
38
|
+
IF current_setting('nextspark.seed_sample_data', true) = 'on' THEN
|
|
39
|
+
RAISE NOTICE 'Sample accounts: kept (development run with sample data).';
|
|
40
|
+
RETURN;
|
|
41
|
+
END IF;
|
|
42
|
+
|
|
43
|
+
SELECT COALESCE(array_agg(DISTINCT "userId"), '{}') INTO sample_users
|
|
44
|
+
FROM "account"
|
|
45
|
+
WHERE "providerId" = 'credential' AND "password" = ANY (sample_passwords);
|
|
46
|
+
|
|
47
|
+
DELETE FROM "account" WHERE "providerId" = 'credential' AND "password" = ANY (sample_passwords);
|
|
48
|
+
DELETE FROM "session" WHERE "userId" = ANY (sample_users) OR token = ANY (sample_session_tokens);
|
|
49
|
+
UPDATE "api_key" SET status = 'inactive', "updatedAt" = now()
|
|
50
|
+
WHERE status IS DISTINCT FROM 'inactive' AND ("userId" = ANY (sample_users) OR "keyHash" = ANY (sample_key_hashes));
|
|
51
|
+
UPDATE "users" SET role = 'member', "updatedAt" = now()
|
|
52
|
+
WHERE id = ANY (sample_users) AND role <> 'member';
|
|
53
|
+
|
|
54
|
+
RAISE NOTICE 'Sample accounts: % disabled (no password, sessions or active API keys; role member).', cardinality(sample_users);
|
|
55
|
+
END $$;
|
|
@@ -7,6 +7,16 @@
|
|
|
7
7
|
-- Theme-specific demo data (TMT.dev users, companies, invoices) is in:
|
|
8
8
|
-- migrations/090_demo_users_teams.sql
|
|
9
9
|
|
|
10
|
+
-- Only a development run that asked for sample data applies this file (see
|
|
11
|
+
-- scripts/db/sample-data.mjs); anything else that runs it, such as a tool that
|
|
12
|
+
-- applies every core .sql file in order, fails here instead of creating these accounts.
|
|
13
|
+
DO $$
|
|
14
|
+
BEGIN
|
|
15
|
+
IF current_setting('nextspark.seed_sample_data', true) IS DISTINCT FROM 'on' THEN
|
|
16
|
+
RAISE EXCEPTION 'Sample data is applied only by `pnpm db:seed` (or NEXTSPARK_SEED_SAMPLE_DATA=1) outside production. If you ran that, the session setting it relies on was lost: a transaction-mode pooler (PgBouncer, Supavisor on port 6543) drops it, so point MIGRATE_DATABASE_URL at a direct connection.';
|
|
17
|
+
END IF;
|
|
18
|
+
END $$;
|
|
19
|
+
|
|
10
20
|
-- ============================================
|
|
11
21
|
-- STEP 1: CREATE CORE TEST USERS
|
|
12
22
|
-- ============================================
|
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.196",
|
|
4
4
|
"description": "NextSpark - The complete SaaS framework for Next.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "NextSpark <hello@nextspark.dev>",
|
|
@@ -496,7 +496,7 @@
|
|
|
496
496
|
"use-intl": "^4.9.1",
|
|
497
497
|
"uuid": "^13.0.0",
|
|
498
498
|
"zod": "^4.3.6",
|
|
499
|
-
"@nextsparkjs/ui": "0.1.0-beta.
|
|
499
|
+
"@nextsparkjs/ui": "0.1.0-beta.196"
|
|
500
500
|
},
|
|
501
501
|
"engines": {
|
|
502
502
|
"node": ">=22.14.0"
|
|
@@ -15,6 +15,9 @@ import test from 'node:test'
|
|
|
15
15
|
import { discoverApiPresets } from '../discovery/api-presets.mjs'
|
|
16
16
|
import { discoverRouteFiles } from '../discovery/plugins.mjs'
|
|
17
17
|
import { generateRouteHandlersRegistry } from '../generators/route-handlers.mjs'
|
|
18
|
+
import { silenceConsoleOutput } from './quiet-console.mjs'
|
|
19
|
+
|
|
20
|
+
silenceConsoleOutput()
|
|
18
21
|
|
|
19
22
|
const presets = endpoint => `export default defineApiEndpoint({\n endpoint: '${endpoint}',\n summary: 'S',\n presets: [{ id: 'a', title: 'A', method: 'GET' }]\n})\n`
|
|
20
23
|
|