@nextsparkjs/core 0.1.0-beta.193 → 0.1.0-beta.195
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/README.md +2 -2
- 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/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/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/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/auth/permissions.d.ts +10 -0
- package/dist/lib/api/auth/permissions.d.ts.map +1 -1
- package/dist/lib/api/auth/permissions.js +7 -0
- 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 +54 -0
- package/dist/lib/api/cors-response.d.ts.map +1 -0
- package/dist/lib/api/cors-response.js +88 -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 -5
- 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 +27 -81
- 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/rate-limit.d.ts +4 -0
- package/dist/lib/api/rate-limit.d.ts.map +1 -1
- package/dist/lib/api/rate-limit.js +17 -38
- package/dist/lib/api/request-origin.d.ts +35 -0
- package/dist/lib/api/request-origin.d.ts.map +1 -0
- package/dist/lib/api/request-origin.js +69 -0
- 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 +2 -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 +15 -14
- 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/external-api-generator.d.ts.map +1 -1
- package/dist/lib/entities/external-api-generator.js +5 -5
- 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/services/subscription.service.d.ts.map +1 -1
- package/dist/lib/services/subscription.service.js +3 -0
- package/dist/lib/utils/cors.d.ts +7 -0
- package/dist/lib/utils/cors.d.ts.map +1 -1
- package/dist/lib/utils/cors.js +8 -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/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 +2 -0
- 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 +2 -0
- package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
- package/dist/routes/api/v1/media/upload/route.js +2 -0
- 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.js +2 -2
- 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/users/[id]/meta/[key]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/users/[id]/meta/[key]/route.js +13 -0
- package/dist/routes/api/v1/users/[id]/route.d.ts.map +1 -1
- package/dist/routes/api/v1/users/[id]/route.js +20 -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/devtools/layout.cc.d.ts.map +1 -1
- package/dist/routes/devtools/layout.cc.js +5 -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/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/blog/package.json +3 -3
- package/dist/templates/projects/crm/package.json +3 -3
- package/dist/templates/projects/productivity/package.json +3 -3
- package/dist/templates/proxy.ts +12 -1
- package/dist/templates/public/favicon.ico +0 -0
- package/package.json +8 -5
- package/scripts/build/auth-readiness.mjs +4 -0
- 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__/build-output.test.mjs +1 -1
- package/scripts/build/registry/__tests__/icons-discovery.test.mjs +3 -0
- package/scripts/build/registry/__tests__/project-mode-root-first.test.mjs +6 -6
- 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/__tests__/write-places.test.mjs +1 -1
- package/scripts/build/registry/contracts/__tests__/contracts-wire.test.mjs +1 -1
- package/scripts/build/registry/contracts/__tests__/contracts.test.mjs +1 -1
- package/scripts/build/registry/contracts/render.mjs +3 -3
- 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 +27 -3
- package/scripts/build/registry/host/__tests__/facade-emitter.test.mjs +9 -9
- 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-mode.test.mjs +1 -1
- package/scripts/build/registry/host/__tests__/host-plan.test.mjs +12 -2
- package/scripts/build/registry/host/__tests__/host-project-composition.test.mjs +1 -1
- package/scripts/build/registry/host/__tests__/host-project.test.mjs +2 -2
- package/scripts/build/registry/host/__tests__/host-robustness.test.mjs +65 -2
- package/scripts/build/registry/host/entity-routes.mjs +9 -3
- package/scripts/build/registry/host/facade-emitter.mjs +2 -2
- package/scripts/build/registry/host/generation.mjs +54 -0
- package/scripts/build/registry/host/next-route-exports.json +2 -2
- package/scripts/build/registry/host/prepare.mjs +3 -0
- package/scripts/build/registry/host/static-imports.mjs +4 -0
- package/scripts/build/routes-manifest.mjs +13 -1
- package/scripts/db/migration-time-limit.mjs +216 -34
- package/scripts/db/run-migrations.mjs +11 -179
- package/scripts/db/ssl-config.mjs +12 -1
- package/scripts/db/verify-theme-migrations.mjs +1 -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/blog/package.json +3 -3
- package/templates/projects/crm/package.json +3 -3
- package/templates/projects/productivity/package.json +3 -3
- package/templates/proxy.ts +12 -1
- package/templates/public/favicon.ico +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
2
|
import { validateAndAuthenticateRequest, createApiResponse, createApiError } from "@nextsparkjs/core/lib/api/helpers";
|
|
3
3
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
4
|
+
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
4
5
|
import { SubscriptionService, MembershipService } from "@nextsparkjs/core/lib/services";
|
|
5
6
|
export const GET = withRateLimitTier(async function GET2(request, props) {
|
|
6
7
|
const { auth, rateLimitResponse, errorResponse } = await validateAndAuthenticateRequest(request, { requiredScope: "billing:read" });
|
|
@@ -28,3 +29,4 @@ export const GET = withRateLimitTier(async function GET2(request, props) {
|
|
|
28
29
|
return createApiError("Failed to fetch subscription", 500);
|
|
29
30
|
}
|
|
30
31
|
}, "read");
|
|
32
|
+
export const OPTIONS = corsPreflight;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* POST /api/v1/teams/[teamId]/usage/[limitSlug] - Track usage
|
|
6
6
|
*/
|
|
7
7
|
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
+
import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
|
|
8
9
|
interface RouteParams {
|
|
9
10
|
params: Promise<{
|
|
10
11
|
teamId: string;
|
|
@@ -13,5 +14,6 @@ interface RouteParams {
|
|
|
13
14
|
}
|
|
14
15
|
export declare const GET: (request: NextRequest, props: RouteParams) => Promise<NextResponse>;
|
|
15
16
|
export declare const POST: (request: NextRequest, props: RouteParams) => Promise<NextResponse>;
|
|
17
|
+
export declare const OPTIONS: typeof corsPreflight;
|
|
16
18
|
export {};
|
|
17
19
|
//# sourceMappingURL=route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAIvE,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACvD;AAED,eAAO,MAAM,GAAG,qEAgCN,CAAA;AAEV,eAAO,MAAM,IAAI,qEA4CN,CAAA;AAEX,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
2
|
import { validateAndAuthenticateRequest, createApiResponse, createApiError } from "@nextsparkjs/core/lib/api/helpers";
|
|
3
3
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
4
|
+
import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
|
|
4
5
|
import { SubscriptionService, UsageService, MembershipService } from "@nextsparkjs/core/lib/services";
|
|
5
6
|
import { trackUsageSchema } from "@nextsparkjs/core/lib/billing/schema";
|
|
6
7
|
export const GET = withRateLimitTier(async function GET2(request, props) {
|
|
@@ -65,3 +66,4 @@ export const POST = withRateLimitTier(async function POST2(request, props) {
|
|
|
65
66
|
return createApiError(errorMessage, 500);
|
|
66
67
|
}
|
|
67
68
|
}, "write");
|
|
69
|
+
export const OPTIONS = corsPreflight;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/routes/api/v1/users/[id]/meta/[key]/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/routes/api/v1/users/[id]/meta/[key]/route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAuBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;2BAmEjD,CAAC;AAEZ;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;2BAoGhD,CAAC;AAEb;;;;GAIG;AACH,eAAO,MAAM,KAAK;YA3GM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;2BA2GpC,CAAA;AAExB;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;2BA8DhD,CAAC"}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
addCorsHeaders
|
|
8
8
|
} from "@nextsparkjs/core/lib/api/helpers";
|
|
9
9
|
import { authenticateRequest, createAuthFailureResponse } from "@nextsparkjs/core/lib/api/auth/dual-auth";
|
|
10
|
+
import { canAccessUser } from "@nextsparkjs/core/lib/api/auth/permissions";
|
|
10
11
|
import * as z from "zod";
|
|
11
12
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
12
13
|
const metadataValueSchema = z.object({
|
|
@@ -33,6 +34,10 @@ export const GET = withRateLimitTier(withApiLogging(async (req, { params }) => {
|
|
|
33
34
|
const response2 = createApiError("User ID is required", 400, null, "MISSING_USER_ID");
|
|
34
35
|
return addCorsHeaders(response2, req);
|
|
35
36
|
}
|
|
37
|
+
if (!canAccessUser(authResult, id, "users:read")) {
|
|
38
|
+
const response2 = createApiError("Insufficient permissions", 403, null, "FORBIDDEN");
|
|
39
|
+
return addCorsHeaders(response2, req);
|
|
40
|
+
}
|
|
36
41
|
if (!key || key.trim() === "") {
|
|
37
42
|
const response2 = createApiError("Metadata key is required", 400, null, "MISSING_META_KEY");
|
|
38
43
|
return addCorsHeaders(response2, req);
|
|
@@ -75,6 +80,10 @@ export const PUT = withRateLimitTier(withApiLogging(async (req, { params }) => {
|
|
|
75
80
|
const response2 = createApiError("User ID is required", 400, null, "MISSING_USER_ID");
|
|
76
81
|
return addCorsHeaders(response2, req);
|
|
77
82
|
}
|
|
83
|
+
if (!canAccessUser(authResult, id, "users:write")) {
|
|
84
|
+
const response2 = createApiError("Insufficient permissions", 403, null, "FORBIDDEN");
|
|
85
|
+
return addCorsHeaders(response2, req);
|
|
86
|
+
}
|
|
78
87
|
if (!key || key.trim() === "") {
|
|
79
88
|
const response2 = createApiError("Metadata key is required", 400, null, "MISSING_META_KEY");
|
|
80
89
|
return addCorsHeaders(response2, req);
|
|
@@ -150,6 +159,10 @@ export const DELETE = withRateLimitTier(withApiLogging(async (req, { params }) =
|
|
|
150
159
|
const response2 = createApiError("User ID is required", 400, null, "MISSING_USER_ID");
|
|
151
160
|
return addCorsHeaders(response2, req);
|
|
152
161
|
}
|
|
162
|
+
if (!canAccessUser(authResult, id, "users:write")) {
|
|
163
|
+
const response2 = createApiError("Insufficient permissions", 403, null, "FORBIDDEN");
|
|
164
|
+
return addCorsHeaders(response2, req);
|
|
165
|
+
}
|
|
153
166
|
if (!key || key.trim() === "") {
|
|
154
167
|
const response2 = createApiError("Metadata key is required", 400, null, "MISSING_META_KEY");
|
|
155
168
|
return addCorsHeaders(response2, req);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/users/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/users/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA+BxD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAoDpC,CAAC;AAGZ,eAAO,MAAM,KAAK;YAEM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAqInC,CAAC;AAGb,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAiEnC,CAAC"}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
processEntityMetadata
|
|
12
12
|
} from "@nextsparkjs/core/lib/api/helpers";
|
|
13
13
|
import { authenticateRequest, createAuthFailureResponse } from "@nextsparkjs/core/lib/api/auth/dual-auth";
|
|
14
|
+
import { canAccessUser, hasAdminPermission } from "@nextsparkjs/core/lib/api/auth/permissions";
|
|
14
15
|
import * as z from "zod";
|
|
15
16
|
import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
|
|
16
17
|
const updateUserSchema = z.object({
|
|
@@ -20,6 +21,7 @@ const updateUserSchema = z.object({
|
|
|
20
21
|
role: z.enum(["member", "superadmin"]).optional(),
|
|
21
22
|
metas: z.record(z.string(), z.any()).optional()
|
|
22
23
|
});
|
|
24
|
+
const resolveUserId = ({ id }, callerId) => id === "me" ? callerId : id;
|
|
23
25
|
export async function OPTIONS(request) {
|
|
24
26
|
return handleCorsPreflightRequest(request);
|
|
25
27
|
}
|
|
@@ -32,11 +34,15 @@ export const GET = withRateLimitTier(withApiLogging(async (req, { params }) => {
|
|
|
32
34
|
if (authResult.rateLimitResponse) {
|
|
33
35
|
return authResult.rateLimitResponse;
|
|
34
36
|
}
|
|
35
|
-
const
|
|
37
|
+
const id = resolveUserId(await params, authResult.user.id);
|
|
36
38
|
if (!id || id.trim() === "") {
|
|
37
39
|
const response2 = createApiError("User ID or email is required", 400, null, "MISSING_IDENTIFIER");
|
|
38
40
|
return addCorsHeaders(response2, req);
|
|
39
41
|
}
|
|
42
|
+
if (!canAccessUser(authResult, id, "users:read")) {
|
|
43
|
+
const response2 = createApiError("Insufficient permissions", 403, null, "FORBIDDEN");
|
|
44
|
+
return addCorsHeaders(response2, req);
|
|
45
|
+
}
|
|
40
46
|
const user = await queryOneWithRLS(
|
|
41
47
|
'SELECT id, email, name, "firstName", "lastName", image, country, timezone, language, role, "emailVerified", "createdAt", "updatedAt" FROM "users" WHERE id = $1 OR email = $1',
|
|
42
48
|
[id],
|
|
@@ -65,14 +71,22 @@ export const PATCH = withRateLimitTier(withApiLogging(async (req, { params }) =>
|
|
|
65
71
|
if (authResult.rateLimitResponse) {
|
|
66
72
|
return authResult.rateLimitResponse;
|
|
67
73
|
}
|
|
68
|
-
const
|
|
74
|
+
const id = resolveUserId(await params, authResult.user.id);
|
|
69
75
|
if (!id || id.trim() === "") {
|
|
70
76
|
const response2 = createApiError("User ID or email is required", 400, null, "MISSING_IDENTIFIER");
|
|
71
77
|
return addCorsHeaders(response2, req);
|
|
72
78
|
}
|
|
79
|
+
if (!canAccessUser(authResult, id, "users:write")) {
|
|
80
|
+
const response2 = createApiError("Insufficient permissions", 403, null, "FORBIDDEN");
|
|
81
|
+
return addCorsHeaders(response2, req);
|
|
82
|
+
}
|
|
73
83
|
const body = await req.json();
|
|
74
84
|
const { metas, ...userData } = body;
|
|
75
85
|
const validatedData = updateUserSchema.parse(userData);
|
|
86
|
+
if (validatedData.role !== void 0 && !hasAdminPermission(authResult, "users:write")) {
|
|
87
|
+
const response2 = createApiError("Only a superadmin can change a role", 403, null, "FORBIDDEN");
|
|
88
|
+
return addCorsHeaders(response2, req);
|
|
89
|
+
}
|
|
76
90
|
const updates = [];
|
|
77
91
|
const values = [];
|
|
78
92
|
let paramCount = 1;
|
|
@@ -157,6 +171,10 @@ export const DELETE = withRateLimitTier(withApiLogging(async (req, { params }) =
|
|
|
157
171
|
const response2 = createApiError("User ID or email is required", 400, null, "MISSING_IDENTIFIER");
|
|
158
172
|
return addCorsHeaders(response2, req);
|
|
159
173
|
}
|
|
174
|
+
if (!hasAdminPermission(authResult, "users:delete")) {
|
|
175
|
+
const response2 = createApiError("Insufficient permissions. Superadmin access required.", 403, null, "FORBIDDEN");
|
|
176
|
+
return addCorsHeaders(response2, req);
|
|
177
|
+
}
|
|
160
178
|
const targetUser = await queryOneWithRLS(
|
|
161
179
|
'SELECT id, email FROM "users" WHERE id = $1 OR email = $1',
|
|
162
180
|
[id],
|
|
@@ -4,52 +4,67 @@ Manage user profiles and account settings.
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
The Users API allows you to view and update user profile information. Users can update their own profile
|
|
7
|
+
The Users API allows you to view and update user profile information. Users can read and update their own profile; a superadmin can manage any user.
|
|
8
8
|
|
|
9
9
|
## Authentication
|
|
10
10
|
|
|
11
11
|
All endpoints require authentication via:
|
|
12
12
|
- **Session cookie** (for browser-based requests)
|
|
13
|
-
- **API Key**
|
|
13
|
+
- **API Key** (for server-to-server requests), sent as `x-api-key: <key>` or `Authorization: Bearer <key>`: it needs the `users:read` scope to read and `users:write` to update, and it answers as the key's owner
|
|
14
|
+
|
|
15
|
+
A user can read and update only themselves; a superadmin can manage any user. Anything else answers `403`.
|
|
14
16
|
|
|
15
17
|
## Endpoints
|
|
16
18
|
|
|
17
19
|
### Get Current User
|
|
18
20
|
`GET /api/v1/users/me`
|
|
19
21
|
|
|
20
|
-
Returns the
|
|
22
|
+
Returns the signed-in user, with a session cookie or an API key. It is `GET /api/v1/users/:id` for the caller's own id, so it takes the same `metas` query parameters and answers with the same fields.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
curl -H "Cookie: <session cookie>" https://yourdomain.com/api/v1/users/me
|
|
26
|
+
curl -H "Authorization: Bearer <api key>" https://yourdomain.com/api/v1/users/me
|
|
27
|
+
curl -H "x-api-key: <api key>" https://yourdomain.com/api/v1/users/me
|
|
28
|
+
```
|
|
21
29
|
|
|
22
30
|
**Example Response:**
|
|
23
31
|
```json
|
|
24
32
|
{
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
"success": true,
|
|
34
|
+
"data": {
|
|
35
|
+
"id": "user_123",
|
|
36
|
+
"email": "john@example.com",
|
|
37
|
+
"name": "John Doe",
|
|
38
|
+
"firstName": "John",
|
|
39
|
+
"lastName": "Doe",
|
|
40
|
+
"image": "/uploads/avatar.png",
|
|
41
|
+
"country": null,
|
|
42
|
+
"timezone": null,
|
|
43
|
+
"language": "en",
|
|
44
|
+
"role": "member",
|
|
45
|
+
"emailVerified": true,
|
|
46
|
+
"createdAt": "2024-01-15T10:30:00Z",
|
|
47
|
+
"updatedAt": "2024-01-15T10:30:00Z"
|
|
48
|
+
}
|
|
37
49
|
}
|
|
38
50
|
```
|
|
39
51
|
|
|
40
52
|
### Update Current User
|
|
41
53
|
`PATCH /api/v1/users/me`
|
|
42
54
|
|
|
43
|
-
Update the
|
|
55
|
+
Update the signed-in user. It is `PATCH /api/v1/users/:id` for the caller's own id, with the same rules: only `firstName`, `lastName`, `language` and `metas` are accepted, and `role` is a superadmin's to change (anyone else gets `403`).
|
|
44
56
|
|
|
45
57
|
**Request Body:**
|
|
46
58
|
```json
|
|
47
59
|
{
|
|
48
|
-
"
|
|
49
|
-
"
|
|
60
|
+
"firstName": "John",
|
|
61
|
+
"lastName": "Smith",
|
|
62
|
+
"metas": { "preferences": { "theme": "dark" } }
|
|
50
63
|
}
|
|
51
64
|
```
|
|
52
65
|
|
|
66
|
+
To store per-user settings (the mobile client's preferences), use the user's metadata: `GET`/`PUT /api/v1/users/:id/meta/:key`.
|
|
67
|
+
|
|
53
68
|
### List Team Members
|
|
54
69
|
`GET /api/v1/users`
|
|
55
70
|
|
|
@@ -63,7 +78,7 @@ Returns all users in the current team.
|
|
|
63
78
|
### Get User by ID
|
|
64
79
|
`GET /api/v1/users/[id]`
|
|
65
80
|
|
|
66
|
-
Returns a specific user's profile
|
|
81
|
+
Returns a specific user's profile. Only that user or a superadmin can read it; `403` otherwise.
|
|
67
82
|
|
|
68
83
|
**Path Parameters:**
|
|
69
84
|
- `id` (string, required): User ID
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NextRequest } from 'next/server';
|
|
2
|
+
import { OPTIONS } from '@nextsparkjs/core/routes/api/v1/users/[id]/route';
|
|
3
|
+
export { OPTIONS };
|
|
4
|
+
export declare const GET: (req: NextRequest) => Promise<import("next/server").NextResponse<unknown>>;
|
|
5
|
+
export declare const PATCH: (req: NextRequest) => Promise<import("next/server").NextResponse<unknown>>;
|
|
6
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/users/me/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAsC,MAAM,kDAAkD,CAAA;AAO9G,OAAO,EAAE,OAAO,EAAE,CAAA;AAClB,eAAO,MAAM,GAAG,GAAI,KAAK,WAAW,yDAAqB,CAAA;AACzD,eAAO,MAAM,KAAK,GAAI,KAAK,WAAW,yDAAuB,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OPTIONS, GET as getUser, PATCH as patchUser } from "@nextsparkjs/core/routes/api/v1/users/[id]/route";
|
|
2
|
+
const me = { params: Promise.resolve({ id: "me" }) };
|
|
3
|
+
export { OPTIONS };
|
|
4
|
+
export const GET = (req) => getUser(req, me);
|
|
5
|
+
export const PATCH = (req) => patchUser(req, me);
|
|
@@ -34,13 +34,13 @@ export default defineApiEndpoint({
|
|
|
34
34
|
{
|
|
35
35
|
id: 'update-profile',
|
|
36
36
|
title: 'Update My Profile',
|
|
37
|
-
description: 'Update current user name',
|
|
37
|
+
description: 'Update the current user first name',
|
|
38
38
|
method: 'PATCH',
|
|
39
39
|
pathParams: {
|
|
40
40
|
id: 'me'
|
|
41
41
|
},
|
|
42
42
|
payload: {
|
|
43
|
-
|
|
43
|
+
firstName: 'Updated'
|
|
44
44
|
},
|
|
45
45
|
tags: ['write', 'profile']
|
|
46
46
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.cc.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/(main)/layout.cc.tsx"],"names":[],"mappings":"AAgBA,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAQtF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
import { MainDashboardShell, enforceEntityPermission } from "../../_internal/dashboard-main-shared.js";
|
|
4
|
+
async function EntityPermission({ children }) {
|
|
5
|
+
await enforceEntityPermission();
|
|
6
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
7
|
+
}
|
|
8
|
+
export default function MainDashboardLayout({ children }) {
|
|
9
|
+
return /* @__PURE__ */ jsx(MainDashboardShell, { children: /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(EntityPermission, { children }) }) });
|
|
10
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/(main)/layout.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/(main)/layout.tsx"],"names":[],"mappings":"AAcA,iBAAe,0BAA0B,CAAC,EACxC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,oDAIA;AAGD,eAAe,0BAA0B,CAAA"}
|
|
@@ -1,50 +1,9 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { redirect } from "next/navigation";
|
|
4
|
-
import { DashboardShell } from "@nextsparkjs/core/components/dashboard/layouts/DashboardShell";
|
|
5
|
-
import { serializeEntityConfig } from "@nextsparkjs/core/lib/entities/serialization";
|
|
6
|
-
import { setEntityRegistry } from "@nextsparkjs/core/lib/entities/queries";
|
|
7
|
-
import { checkPermission } from "@nextsparkjs/core/lib/permissions/check";
|
|
8
|
-
import { getDashboardPermissionContext } from "@nextsparkjs/core/lib/auth/request-session";
|
|
9
|
-
import { isValidPermission } from "@nextsparkjs/core/lib/permissions/init";
|
|
10
|
-
import { ENTITY_REGISTRY, ENTITY_METADATA } from "@nextsparkjs/registries/entity-registry";
|
|
11
|
-
setEntityRegistry(ENTITY_REGISTRY, ENTITY_METADATA);
|
|
12
|
-
function parseEntityFromPathname(pathname) {
|
|
13
|
-
const match = pathname.match(/^\/dashboard\/([^/]+)(?:\/(.*))?$/);
|
|
14
|
-
if (!match) return null;
|
|
15
|
-
const entity = match[1];
|
|
16
|
-
const rest = match[2] || "";
|
|
17
|
-
if (rest === "" || rest === "/") return { entity, action: "list" };
|
|
18
|
-
if (rest === "create") return { entity, action: "create" };
|
|
19
|
-
if (rest.match(/^[^/]+\/edit$/)) return { entity, action: "update" };
|
|
20
|
-
if (rest.match(/^[^/]+$/)) return { entity, action: "read" };
|
|
21
|
-
return { entity, action: "read" };
|
|
22
|
-
}
|
|
23
|
-
function isEntityConfig(entity) {
|
|
24
|
-
return "slug" in entity;
|
|
25
|
-
}
|
|
2
|
+
import { MainDashboardShell, enforceEntityPermission } from "../../_internal/dashboard-main-shared.js";
|
|
26
3
|
async function DefaultMainDashboardLayout({
|
|
27
4
|
children
|
|
28
5
|
}) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const serializedEntities = entities.map(serializeEntityConfig);
|
|
32
|
-
const headersList = await headers();
|
|
33
|
-
const pathname = headersList.get("x-pathname") || "";
|
|
34
|
-
const { userId, teamId } = await getDashboardPermissionContext();
|
|
35
|
-
if (userId && teamId && pathname) {
|
|
36
|
-
const parsed = parseEntityFromPathname(pathname);
|
|
37
|
-
if (parsed) {
|
|
38
|
-
const { entity, action } = parsed;
|
|
39
|
-
const permission = `${entity}.${action}`;
|
|
40
|
-
if (isValidPermission(`${entity}.list`)) {
|
|
41
|
-
const hasPermission = await checkPermission(userId, teamId, permission);
|
|
42
|
-
if (!hasPermission) {
|
|
43
|
-
redirect(`/dashboard/permission-denied?entity=${entity}&action=${action}`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return /* @__PURE__ */ jsx(DashboardShell, { entities: serializedEntities, children });
|
|
6
|
+
await enforceEntityPermission();
|
|
7
|
+
return /* @__PURE__ */ jsx(MainDashboardShell, { children });
|
|
49
8
|
}
|
|
50
9
|
export default DefaultMainDashboardLayout;
|
|
@@ -4,6 +4,6 @@ interface PermissionDeniedPageProps {
|
|
|
4
4
|
action?: string;
|
|
5
5
|
}>;
|
|
6
6
|
}
|
|
7
|
-
declare function PermissionDeniedPage({ searchParams }: PermissionDeniedPageProps):
|
|
7
|
+
declare function PermissionDeniedPage({ searchParams }: PermissionDeniedPageProps): import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export default PermissionDeniedPage;
|
|
9
9
|
//# sourceMappingURL=page.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/permission-denied/page.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/permission-denied/page.tsx"],"names":[],"mappings":"AASA,UAAU,yBAAyB;IACjC,YAAY,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAC,CAAA;CACH;AAkBD,iBAAS,oBAAoB,CAAC,EAAE,YAAY,EAAE,EAAE,yBAAyB,2CAMxE;AAED,eAAe,oBAAoB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense } from "react";
|
|
2
3
|
import { NoPermission } from "@nextsparkjs/core/components/permissions/NoPermission";
|
|
3
|
-
async function
|
|
4
|
+
async function DeniedMessage({
|
|
4
5
|
searchParams
|
|
5
6
|
}) {
|
|
6
7
|
const { entity, action } = await searchParams;
|
|
@@ -14,4 +15,7 @@ async function PermissionDeniedPage({
|
|
|
14
15
|
}
|
|
15
16
|
);
|
|
16
17
|
}
|
|
18
|
+
function PermissionDeniedPage({ searchParams }) {
|
|
19
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(DeniedMessage, { searchParams }) });
|
|
20
|
+
}
|
|
17
21
|
export default PermissionDeniedPage;
|
|
@@ -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);
|
|
@@ -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",
|
|
@@ -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
|