@nextsparkjs/core 0.1.0-beta.103 → 0.1.0-beta.105

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.
Files changed (56) hide show
  1. package/dist/lib/permissions/system.d.ts.map +1 -1
  2. package/dist/lib/permissions/system.js +40 -1
  3. package/dist/styles/classes.json +1 -1
  4. package/dist/templates/app/(auth)/accept-invite/[token]/page.tsx +4 -1
  5. package/dist/templates/app/dashboard/(main)/[entity]/loading.tsx +5 -2
  6. package/dist/templates/app/dashboard/(main)/loading.tsx +4 -1
  7. package/dist/templates/app/dashboard/(main)/patterns/[id]/edit/page.tsx +4 -1
  8. package/dist/templates/app/dashboard/(main)/patterns/[id]/page.tsx +4 -1
  9. package/dist/templates/app/dashboard/(main)/patterns/[id]/reports/page.tsx +4 -1
  10. package/dist/templates/app/dashboard/(main)/patterns/create/page.tsx +4 -1
  11. package/dist/templates/app/dashboard/(main)/patterns/page.tsx +4 -1
  12. package/dist/templates/app/dashboard/features/analytics/page.tsx +4 -1
  13. package/dist/templates/app/dashboard/features/automation/page.tsx +4 -1
  14. package/dist/templates/app/dashboard/features/layout.tsx +5 -2
  15. package/dist/templates/app/dashboard/features/loading.tsx +4 -1
  16. package/dist/templates/app/dashboard/features/webhooks/page.tsx +4 -1
  17. package/dist/templates/app/dashboard/permission-denied/page.tsx +4 -1
  18. package/dist/templates/app/dashboard/settings/api-keys/loading.tsx +4 -1
  19. package/dist/templates/app/dashboard/settings/billing/loading.tsx +4 -1
  20. package/dist/templates/app/dashboard/settings/invoices/loading.tsx +4 -1
  21. package/dist/templates/app/dashboard/settings/loading.tsx +4 -1
  22. package/dist/templates/app/dashboard/settings/notifications/loading.tsx +4 -1
  23. package/dist/templates/app/dashboard/settings/page.tsx +2 -1
  24. package/dist/templates/app/dashboard/settings/password/loading.tsx +4 -1
  25. package/dist/templates/app/dashboard/settings/plans/loading.tsx +4 -1
  26. package/dist/templates/app/dashboard/settings/profile/loading.tsx +4 -1
  27. package/dist/templates/app/dashboard/settings/security/loading.tsx +4 -1
  28. package/dist/templates/app/dashboard/settings/teams/loading.tsx +4 -1
  29. package/dist/templates/app/dashboard/settings/teams/permissions/page.tsx +4 -1
  30. package/package.json +2 -2
  31. package/templates/app/(auth)/accept-invite/[token]/page.tsx +4 -1
  32. package/templates/app/dashboard/(main)/[entity]/loading.tsx +5 -2
  33. package/templates/app/dashboard/(main)/loading.tsx +4 -1
  34. package/templates/app/dashboard/(main)/patterns/[id]/edit/page.tsx +4 -1
  35. package/templates/app/dashboard/(main)/patterns/[id]/page.tsx +4 -1
  36. package/templates/app/dashboard/(main)/patterns/[id]/reports/page.tsx +4 -1
  37. package/templates/app/dashboard/(main)/patterns/create/page.tsx +4 -1
  38. package/templates/app/dashboard/(main)/patterns/page.tsx +4 -1
  39. package/templates/app/dashboard/features/analytics/page.tsx +4 -1
  40. package/templates/app/dashboard/features/automation/page.tsx +4 -1
  41. package/templates/app/dashboard/features/layout.tsx +5 -2
  42. package/templates/app/dashboard/features/loading.tsx +4 -1
  43. package/templates/app/dashboard/features/webhooks/page.tsx +4 -1
  44. package/templates/app/dashboard/permission-denied/page.tsx +4 -1
  45. package/templates/app/dashboard/settings/api-keys/loading.tsx +4 -1
  46. package/templates/app/dashboard/settings/billing/loading.tsx +4 -1
  47. package/templates/app/dashboard/settings/invoices/loading.tsx +4 -1
  48. package/templates/app/dashboard/settings/loading.tsx +4 -1
  49. package/templates/app/dashboard/settings/notifications/loading.tsx +4 -1
  50. package/templates/app/dashboard/settings/page.tsx +2 -1
  51. package/templates/app/dashboard/settings/password/loading.tsx +4 -1
  52. package/templates/app/dashboard/settings/plans/loading.tsx +4 -1
  53. package/templates/app/dashboard/settings/profile/loading.tsx +4 -1
  54. package/templates/app/dashboard/settings/security/loading.tsx +4 -1
  55. package/templates/app/dashboard/settings/teams/loading.tsx +4 -1
  56. package/templates/app/dashboard/settings/teams/permissions/page.tsx +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/lib/permissions/system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,EAAE,qBA6GrC,CAAA"}
1
+ {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/lib/permissions/system.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,EAAE,qBAqJrC,CAAA"}
@@ -64,6 +64,36 @@ const CORE_PERMISSIONS_CONFIG = {
64
64
  description: "Can connect and configure external integrations",
65
65
  category: "Settings",
66
66
  roles: ["owner", "admin"]
67
+ },
68
+ // Media Library
69
+ {
70
+ id: "media.read",
71
+ label: "View Media",
72
+ description: "Can browse and view media files in the library",
73
+ category: "Media",
74
+ roles: ["owner", "admin", "member", "viewer"]
75
+ },
76
+ {
77
+ id: "media.upload",
78
+ label: "Upload Media",
79
+ description: "Can upload images, videos, and other media files",
80
+ category: "Media",
81
+ roles: ["owner", "admin", "member"]
82
+ },
83
+ {
84
+ id: "media.update",
85
+ label: "Edit Media",
86
+ description: "Can edit media metadata, tags, and captions",
87
+ category: "Media",
88
+ roles: ["owner", "admin"]
89
+ },
90
+ {
91
+ id: "media.delete",
92
+ label: "Delete Media",
93
+ description: "Can permanently delete media files",
94
+ category: "Media",
95
+ roles: ["owner", "admin"],
96
+ dangerous: true
67
97
  }
68
98
  ],
69
99
  /**
@@ -78,7 +108,10 @@ const CORE_PERMISSIONS_CONFIG = {
78
108
  "teams.change_roles",
79
109
  "teams.settings",
80
110
  "settings.api_keys",
81
- "settings.integrations"
111
+ "settings.integrations",
112
+ "media.read",
113
+ "media.upload",
114
+ "media.update"
82
115
  ],
83
116
  member: [],
84
117
  // Permissions come from entity configs
@@ -99,6 +132,12 @@ const CORE_PERMISSIONS_CONFIG = {
99
132
  label: "Settings",
100
133
  categories: ["Settings"]
101
134
  },
135
+ {
136
+ id: "media",
137
+ label: "Media",
138
+ description: "Media library management",
139
+ categories: ["Media"]
140
+ },
102
141
  {
103
142
  id: "entities",
104
143
  label: "Entities",
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-02-19T13:38:18.496Z",
2
+ "generated": "2026-02-24T05:05:49.640Z",
3
3
  "totalClasses": 1071,
4
4
  "classes": [
5
5
  "!text-2xl",
@@ -9,6 +9,7 @@ import { Loader2, CheckCircle, XCircle, Users, LogIn, UserPlus } from 'lucide-re
9
9
  import { toast } from 'sonner'
10
10
  import Link from 'next/link'
11
11
  import { sel } from '@nextsparkjs/core/selectors'
12
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
12
13
 
13
14
  type InvitationStatus = 'loading' | 'valid' | 'accepting' | 'accepted' | 'error' | 'expired' | 'not_found' | 'email_mismatch' | 'already_member' | 'requires_auth'
14
15
 
@@ -19,7 +20,7 @@ interface InvitationInfo {
19
20
  email: string
20
21
  }
21
22
 
22
- export default function AcceptInvitePage() {
23
+ function AcceptInvitePage() {
23
24
  const params = useParams()
24
25
  const router = useRouter()
25
26
  const { user, isLoading: authLoading } = useAuth()
@@ -333,3 +334,5 @@ export default function AcceptInvitePage() {
333
334
  </div>
334
335
  )
335
336
  }
337
+
338
+ export default getTemplateOrDefaultClient('app/(auth)/accept-invite/[token]/page.tsx', AcceptInvitePage)
@@ -1,6 +1,7 @@
1
1
  import { Skeleton } from '@nextsparkjs/core/components/ui/skeleton'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function EntityLoading() {
4
+ function EntityLoading() {
4
5
  return (
5
6
  <div className="space-y-6 p-6">
6
7
  {/* Header skeleton */}
@@ -58,4 +59,6 @@ export default function EntityLoading() {
58
59
  </div>
59
60
  </div>
60
61
  )
61
- }
62
+ }
63
+
64
+ export default getTemplateOrDefault('app/dashboard/(main)/[entity]/loading.tsx', EntityLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonDashboardHome } from '@nextsparkjs/core/components/ui/skeleton-dashboard'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function DashboardLoading() {
4
+ function DashboardLoading() {
4
5
  return <SkeletonDashboardHome />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/(main)/loading.tsx', DashboardLoading)
@@ -14,8 +14,9 @@ import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrapper
14
14
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
15
15
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert'
16
16
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
18
 
18
- export default function PatternEditPage() {
19
+ function PatternEditPage() {
19
20
  const params = useParams()
20
21
  const router = useRouter()
21
22
  const [entityConfig, setEntityConfig] = useState<ClientEntityConfig | null>(null)
@@ -112,3 +113,5 @@ export default function PatternEditPage() {
112
113
  />
113
114
  )
114
115
  }
116
+
117
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/[id]/edit/page.tsx', PatternEditPage)
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { redirect } from 'next/navigation'
8
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
8
9
 
9
10
  interface PageProps {
10
11
  params: Promise<{
@@ -12,9 +13,11 @@ interface PageProps {
12
13
  }>
13
14
  }
14
15
 
15
- export default async function PatternDetailPage({ params }: PageProps) {
16
+ async function PatternDetailPage({ params }: PageProps) {
16
17
  const resolvedParams = await params
17
18
 
18
19
  // Patterns are builder-enabled, so redirect to edit view
19
20
  redirect(`/dashboard/patterns/${resolvedParams.id}/edit`)
20
21
  }
22
+
23
+ export default getTemplateOrDefault('app/dashboard/(main)/patterns/[id]/page.tsx', PatternDetailPage)
@@ -17,6 +17,7 @@ import { Button } from '@nextsparkjs/core/components/ui/button'
17
17
  import { Alert, AlertDescription, AlertTitle } from '@nextsparkjs/core/components/ui/alert'
18
18
  import { Skeleton } from '@nextsparkjs/core/components/ui/skeleton'
19
19
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
20
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
20
21
 
21
22
  interface PatternData {
22
23
  id: string
@@ -24,7 +25,7 @@ interface PatternData {
24
25
  title?: string
25
26
  }
26
27
 
27
- export default function PatternReportsPage() {
28
+ function PatternReportsPage() {
28
29
  const params = useParams()
29
30
  const router = useRouter()
30
31
  const patternId = params.id as string
@@ -169,3 +170,5 @@ export default function PatternReportsPage() {
169
170
  </div>
170
171
  )
171
172
  }
173
+
174
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/[id]/reports/page.tsx', PatternReportsPage)
@@ -12,8 +12,9 @@ import { clientEntityRegistry, ensureClientInitialized, type ClientEntityConfig
12
12
  import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityFormWrapper'
13
13
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
14
14
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert'
15
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
15
16
 
16
- export default function PatternsCreatePage() {
17
+ function PatternsCreatePage() {
17
18
  const router = useRouter()
18
19
  const [entityConfig, setEntityConfig] = useState<ClientEntityConfig | null>(null)
19
20
  const [loading, setLoading] = useState(true)
@@ -84,3 +85,5 @@ export default function PatternsCreatePage() {
84
85
  />
85
86
  )
86
87
  }
88
+
89
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/create/page.tsx', PatternsCreatePage)
@@ -28,6 +28,7 @@ import type { Permission } from '@nextsparkjs/core/lib/permissions/types'
28
28
  import type { QuickAction, DropdownAction } from '@nextsparkjs/core/components/entities/entity-table.types'
29
29
  import { sel } from '@nextsparkjs/core/lib/test'
30
30
  import { toast } from 'sonner'
31
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
31
32
 
32
33
  interface PatternItem {
33
34
  id: string
@@ -37,7 +38,7 @@ interface PatternItem {
37
38
  [key: string]: unknown
38
39
  }
39
40
 
40
- export default function PatternsListPage() {
41
+ function PatternsListPage() {
41
42
  const entityType = 'patterns'
42
43
  const router = useRouter()
43
44
 
@@ -442,3 +443,5 @@ export default function PatternsListPage() {
442
443
  </div>
443
444
  )
444
445
  }
446
+
447
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/page.tsx', PatternsListPage)
@@ -4,8 +4,9 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { BarChart3 } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
8
 
8
- export default function AdvancedAnalyticsPage() {
9
+ function AdvancedAnalyticsPage() {
9
10
  const t = useTranslations('features')
10
11
 
11
12
  return (
@@ -33,3 +34,5 @@ export default function AdvancedAnalyticsPage() {
33
34
  </div>
34
35
  )
35
36
  }
37
+
38
+ export default getTemplateOrDefaultClient('app/dashboard/features/analytics/page.tsx', AdvancedAnalyticsPage)
@@ -4,8 +4,9 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { Zap } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
8
 
8
- export default function TaskAutomationPage() {
9
+ function TaskAutomationPage() {
9
10
  const t = useTranslations('features')
10
11
 
11
12
  return (
@@ -33,3 +34,5 @@ export default function TaskAutomationPage() {
33
34
  </div>
34
35
  )
35
36
  }
37
+
38
+ export default getTemplateOrDefaultClient('app/dashboard/features/automation/page.tsx', TaskAutomationPage)
@@ -1,13 +1,16 @@
1
- import { ReactNode } from 'react'
1
+ import { type ReactNode } from 'react'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
4
  interface FeaturesLayoutProps {
4
5
  children: ReactNode
5
6
  }
6
7
 
7
- export default function FeaturesLayout({ children }: FeaturesLayoutProps) {
8
+ function FeaturesLayout({ children }: FeaturesLayoutProps) {
8
9
  return (
9
10
  <div className="container py-8" data-cy="features-layout">
10
11
  {children}
11
12
  </div>
12
13
  )
13
14
  }
15
+
16
+ export default getTemplateOrDefault('app/dashboard/features/layout.tsx', FeaturesLayout)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonFeaturePlaceholder } from '@nextsparkjs/core/components/ui/skeleton-features'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function FeaturesLoading() {
4
+ function FeaturesLoading() {
4
5
  return <SkeletonFeaturePlaceholder />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/features/loading.tsx', FeaturesLoading)
@@ -4,8 +4,9 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { Webhook } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
8
 
8
- export default function WebhooksPage() {
9
+ function WebhooksPage() {
9
10
  const t = useTranslations('features')
10
11
 
11
12
  return (
@@ -33,3 +34,5 @@ export default function WebhooksPage() {
33
34
  </div>
34
35
  )
35
36
  }
37
+
38
+ export default getTemplateOrDefaultClient('app/dashboard/features/webhooks/page.tsx', WebhooksPage)
@@ -5,6 +5,7 @@
5
5
  * This page is displayed when a user attempts to access a resource they don't have permission for.
6
6
  */
7
7
  import { NoPermission } from '@nextsparkjs/core/components/permissions/NoPermission'
8
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
8
9
 
9
10
  interface PermissionDeniedPageProps {
10
11
  searchParams: Promise<{
@@ -13,7 +14,7 @@ interface PermissionDeniedPageProps {
13
14
  }>
14
15
  }
15
16
 
16
- export default async function PermissionDeniedPage({
17
+ async function PermissionDeniedPage({
17
18
  searchParams
18
19
  }: PermissionDeniedPageProps) {
19
20
  const { entity, action } = await searchParams
@@ -27,3 +28,5 @@ export default async function PermissionDeniedPage({
27
28
  />
28
29
  )
29
30
  }
31
+
32
+ export default getTemplateOrDefault('app/dashboard/permission-denied/page.tsx', PermissionDeniedPage)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonApiKeysPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function ApiKeysLoading() {
4
+ function ApiKeysLoading() {
4
5
  return <SkeletonApiKeysPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/api-keys/loading.tsx', ApiKeysLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonBillingPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function BillingLoading() {
4
+ function BillingLoading() {
4
5
  return <SkeletonBillingPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/billing/loading.tsx', BillingLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonInvoicesPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function InvoicesLoading() {
4
+ function InvoicesLoading() {
4
5
  return <SkeletonInvoicesPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/invoices/loading.tsx', InvoicesLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonSettingsOverview } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function SettingsLoading() {
4
+ function SettingsLoading() {
4
5
  return <SkeletonSettingsOverview />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/loading.tsx', SettingsLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonNotificationsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function NotificationsLoading() {
4
+ function NotificationsLoading() {
4
5
  return <SkeletonNotificationsPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/notifications/loading.tsx', NotificationsLoading)
@@ -14,6 +14,7 @@ import {
14
14
  Key,
15
15
  type LucideIcon
16
16
  } from 'lucide-react'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
18
 
18
19
  // Icon mapping for settings pages
19
20
  const SETTINGS_ICONS: Record<string, LucideIcon> = {
@@ -89,4 +90,4 @@ function SettingsPage() {
89
90
  )
90
91
  }
91
92
 
92
- export default SettingsPage
93
+ export default getTemplateOrDefaultClient('app/dashboard/settings/page.tsx', SettingsPage)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonPasswordPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function PasswordLoading() {
4
+ function PasswordLoading() {
4
5
  return <SkeletonPasswordPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/password/loading.tsx', PasswordLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonPlansPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function PlansLoading() {
4
+ function PlansLoading() {
4
5
  return <SkeletonPlansPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/plans/loading.tsx', PlansLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonProfileForm } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function ProfileLoading() {
4
+ function ProfileLoading() {
4
5
  return <SkeletonProfileForm />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/profile/loading.tsx', ProfileLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonSecurityPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function SecurityLoading() {
4
+ function SecurityLoading() {
4
5
  return <SkeletonSecurityPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/security/loading.tsx', SecurityLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonTeamsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function TeamsLoading() {
4
+ function TeamsLoading() {
4
5
  return <SkeletonTeamsPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/teams/loading.tsx', TeamsLoading)
@@ -4,6 +4,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@nextsparkjs/core/comp
4
4
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nextsparkjs/core/components/ui/card'
5
5
  // Use PermissionService which reads from the build-time generated registry
6
6
  import { PermissionService } from '@nextsparkjs/core/lib/services/permission.service'
7
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
7
8
 
8
9
  /**
9
10
  * Team Permissions Page
@@ -11,7 +12,7 @@ import { PermissionService } from '@nextsparkjs/core/lib/services/permission.ser
11
12
  * Displays a visual permissions matrix showing what each team role can do.
12
13
  * Organized by categories with tabs for easy navigation.
13
14
  */
14
- export default function TeamPermissionsPage() {
15
+ function TeamPermissionsPage() {
15
16
  const t = useTranslations('permissions')
16
17
 
17
18
  // Get all unique categories from registry
@@ -90,3 +91,5 @@ function RoleCard({ role }: { role: 'owner' | 'admin' | 'member' | 'viewer' }) {
90
91
  </div>
91
92
  )
92
93
  }
94
+
95
+ export default getTemplateOrDefault('app/dashboard/settings/teams/permissions/page.tsx', TeamPermissionsPage)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/core",
3
- "version": "0.1.0-beta.103",
3
+ "version": "0.1.0-beta.105",
4
4
  "description": "NextSpark - The complete SaaS framework for Next.js",
5
5
  "license": "MIT",
6
6
  "author": "NextSpark <hello@nextspark.dev>",
@@ -453,7 +453,7 @@
453
453
  "tailwind-merge": "^3.3.1",
454
454
  "uuid": "^13.0.0",
455
455
  "zod": "^4.1.5",
456
- "@nextsparkjs/testing": "0.1.0-beta.103"
456
+ "@nextsparkjs/testing": "0.1.0-beta.105"
457
457
  },
458
458
  "scripts": {
459
459
  "postinstall": "node scripts/postinstall.mjs || true",
@@ -9,6 +9,7 @@ import { Loader2, CheckCircle, XCircle, Users, LogIn, UserPlus } from 'lucide-re
9
9
  import { toast } from 'sonner'
10
10
  import Link from 'next/link'
11
11
  import { sel } from '@nextsparkjs/core/selectors'
12
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
12
13
 
13
14
  type InvitationStatus = 'loading' | 'valid' | 'accepting' | 'accepted' | 'error' | 'expired' | 'not_found' | 'email_mismatch' | 'already_member' | 'requires_auth'
14
15
 
@@ -19,7 +20,7 @@ interface InvitationInfo {
19
20
  email: string
20
21
  }
21
22
 
22
- export default function AcceptInvitePage() {
23
+ function AcceptInvitePage() {
23
24
  const params = useParams()
24
25
  const router = useRouter()
25
26
  const { user, isLoading: authLoading } = useAuth()
@@ -333,3 +334,5 @@ export default function AcceptInvitePage() {
333
334
  </div>
334
335
  )
335
336
  }
337
+
338
+ export default getTemplateOrDefaultClient('app/(auth)/accept-invite/[token]/page.tsx', AcceptInvitePage)
@@ -1,6 +1,7 @@
1
1
  import { Skeleton } from '@nextsparkjs/core/components/ui/skeleton'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function EntityLoading() {
4
+ function EntityLoading() {
4
5
  return (
5
6
  <div className="space-y-6 p-6">
6
7
  {/* Header skeleton */}
@@ -58,4 +59,6 @@ export default function EntityLoading() {
58
59
  </div>
59
60
  </div>
60
61
  )
61
- }
62
+ }
63
+
64
+ export default getTemplateOrDefault('app/dashboard/(main)/[entity]/loading.tsx', EntityLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonDashboardHome } from '@nextsparkjs/core/components/ui/skeleton-dashboard'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function DashboardLoading() {
4
+ function DashboardLoading() {
4
5
  return <SkeletonDashboardHome />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/(main)/loading.tsx', DashboardLoading)
@@ -14,8 +14,9 @@ import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrapper
14
14
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
15
15
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert'
16
16
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
18
 
18
- export default function PatternEditPage() {
19
+ function PatternEditPage() {
19
20
  const params = useParams()
20
21
  const router = useRouter()
21
22
  const [entityConfig, setEntityConfig] = useState<ClientEntityConfig | null>(null)
@@ -112,3 +113,5 @@ export default function PatternEditPage() {
112
113
  />
113
114
  )
114
115
  }
116
+
117
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/[id]/edit/page.tsx', PatternEditPage)
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { redirect } from 'next/navigation'
8
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
8
9
 
9
10
  interface PageProps {
10
11
  params: Promise<{
@@ -12,9 +13,11 @@ interface PageProps {
12
13
  }>
13
14
  }
14
15
 
15
- export default async function PatternDetailPage({ params }: PageProps) {
16
+ async function PatternDetailPage({ params }: PageProps) {
16
17
  const resolvedParams = await params
17
18
 
18
19
  // Patterns are builder-enabled, so redirect to edit view
19
20
  redirect(`/dashboard/patterns/${resolvedParams.id}/edit`)
20
21
  }
22
+
23
+ export default getTemplateOrDefault('app/dashboard/(main)/patterns/[id]/page.tsx', PatternDetailPage)
@@ -17,6 +17,7 @@ import { Button } from '@nextsparkjs/core/components/ui/button'
17
17
  import { Alert, AlertDescription, AlertTitle } from '@nextsparkjs/core/components/ui/alert'
18
18
  import { Skeleton } from '@nextsparkjs/core/components/ui/skeleton'
19
19
  import { getEntityData } from '@nextsparkjs/core/lib/api/entities'
20
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
20
21
 
21
22
  interface PatternData {
22
23
  id: string
@@ -24,7 +25,7 @@ interface PatternData {
24
25
  title?: string
25
26
  }
26
27
 
27
- export default function PatternReportsPage() {
28
+ function PatternReportsPage() {
28
29
  const params = useParams()
29
30
  const router = useRouter()
30
31
  const patternId = params.id as string
@@ -169,3 +170,5 @@ export default function PatternReportsPage() {
169
170
  </div>
170
171
  )
171
172
  }
173
+
174
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/[id]/reports/page.tsx', PatternReportsPage)
@@ -12,8 +12,9 @@ import { clientEntityRegistry, ensureClientInitialized, type ClientEntityConfig
12
12
  import { EntityFormWrapper } from '@nextsparkjs/core/components/entities/wrappers/EntityFormWrapper'
13
13
  import { BuilderEditorView } from '@nextsparkjs/core/components/dashboard/block-editor/builder-editor-view'
14
14
  import { Alert, AlertDescription } from '@nextsparkjs/core/components/ui/alert'
15
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
15
16
 
16
- export default function PatternsCreatePage() {
17
+ function PatternsCreatePage() {
17
18
  const router = useRouter()
18
19
  const [entityConfig, setEntityConfig] = useState<ClientEntityConfig | null>(null)
19
20
  const [loading, setLoading] = useState(true)
@@ -84,3 +85,5 @@ export default function PatternsCreatePage() {
84
85
  />
85
86
  )
86
87
  }
88
+
89
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/create/page.tsx', PatternsCreatePage)
@@ -28,6 +28,7 @@ import type { Permission } from '@nextsparkjs/core/lib/permissions/types'
28
28
  import type { QuickAction, DropdownAction } from '@nextsparkjs/core/components/entities/entity-table.types'
29
29
  import { sel } from '@nextsparkjs/core/lib/test'
30
30
  import { toast } from 'sonner'
31
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
31
32
 
32
33
  interface PatternItem {
33
34
  id: string
@@ -37,7 +38,7 @@ interface PatternItem {
37
38
  [key: string]: unknown
38
39
  }
39
40
 
40
- export default function PatternsListPage() {
41
+ function PatternsListPage() {
41
42
  const entityType = 'patterns'
42
43
  const router = useRouter()
43
44
 
@@ -442,3 +443,5 @@ export default function PatternsListPage() {
442
443
  </div>
443
444
  )
444
445
  }
446
+
447
+ export default getTemplateOrDefaultClient('app/dashboard/(main)/patterns/page.tsx', PatternsListPage)
@@ -4,8 +4,9 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { BarChart3 } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
8
 
8
- export default function AdvancedAnalyticsPage() {
9
+ function AdvancedAnalyticsPage() {
9
10
  const t = useTranslations('features')
10
11
 
11
12
  return (
@@ -33,3 +34,5 @@ export default function AdvancedAnalyticsPage() {
33
34
  </div>
34
35
  )
35
36
  }
37
+
38
+ export default getTemplateOrDefaultClient('app/dashboard/features/analytics/page.tsx', AdvancedAnalyticsPage)
@@ -4,8 +4,9 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { Zap } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
8
 
8
- export default function TaskAutomationPage() {
9
+ function TaskAutomationPage() {
9
10
  const t = useTranslations('features')
10
11
 
11
12
  return (
@@ -33,3 +34,5 @@ export default function TaskAutomationPage() {
33
34
  </div>
34
35
  )
35
36
  }
37
+
38
+ export default getTemplateOrDefaultClient('app/dashboard/features/automation/page.tsx', TaskAutomationPage)
@@ -1,13 +1,16 @@
1
- import { ReactNode } from 'react'
1
+ import { type ReactNode } from 'react'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
4
  interface FeaturesLayoutProps {
4
5
  children: ReactNode
5
6
  }
6
7
 
7
- export default function FeaturesLayout({ children }: FeaturesLayoutProps) {
8
+ function FeaturesLayout({ children }: FeaturesLayoutProps) {
8
9
  return (
9
10
  <div className="container py-8" data-cy="features-layout">
10
11
  {children}
11
12
  </div>
12
13
  )
13
14
  }
15
+
16
+ export default getTemplateOrDefault('app/dashboard/features/layout.tsx', FeaturesLayout)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonFeaturePlaceholder } from '@nextsparkjs/core/components/ui/skeleton-features'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function FeaturesLoading() {
4
+ function FeaturesLoading() {
4
5
  return <SkeletonFeaturePlaceholder />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/features/loading.tsx', FeaturesLoading)
@@ -4,8 +4,9 @@ import { FeatureGate } from '@nextsparkjs/core/components/billing/FeatureGate'
4
4
  import { FeaturePlaceholder } from '@nextsparkjs/core/components/billing/FeaturePlaceholder'
5
5
  import { Webhook } from 'lucide-react'
6
6
  import { useTranslations } from 'next-intl'
7
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
7
8
 
8
- export default function WebhooksPage() {
9
+ function WebhooksPage() {
9
10
  const t = useTranslations('features')
10
11
 
11
12
  return (
@@ -33,3 +34,5 @@ export default function WebhooksPage() {
33
34
  </div>
34
35
  )
35
36
  }
37
+
38
+ export default getTemplateOrDefaultClient('app/dashboard/features/webhooks/page.tsx', WebhooksPage)
@@ -5,6 +5,7 @@
5
5
  * This page is displayed when a user attempts to access a resource they don't have permission for.
6
6
  */
7
7
  import { NoPermission } from '@nextsparkjs/core/components/permissions/NoPermission'
8
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
8
9
 
9
10
  interface PermissionDeniedPageProps {
10
11
  searchParams: Promise<{
@@ -13,7 +14,7 @@ interface PermissionDeniedPageProps {
13
14
  }>
14
15
  }
15
16
 
16
- export default async function PermissionDeniedPage({
17
+ async function PermissionDeniedPage({
17
18
  searchParams
18
19
  }: PermissionDeniedPageProps) {
19
20
  const { entity, action } = await searchParams
@@ -27,3 +28,5 @@ export default async function PermissionDeniedPage({
27
28
  />
28
29
  )
29
30
  }
31
+
32
+ export default getTemplateOrDefault('app/dashboard/permission-denied/page.tsx', PermissionDeniedPage)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonApiKeysPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function ApiKeysLoading() {
4
+ function ApiKeysLoading() {
4
5
  return <SkeletonApiKeysPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/api-keys/loading.tsx', ApiKeysLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonBillingPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function BillingLoading() {
4
+ function BillingLoading() {
4
5
  return <SkeletonBillingPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/billing/loading.tsx', BillingLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonInvoicesPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function InvoicesLoading() {
4
+ function InvoicesLoading() {
4
5
  return <SkeletonInvoicesPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/invoices/loading.tsx', InvoicesLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonSettingsOverview } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function SettingsLoading() {
4
+ function SettingsLoading() {
4
5
  return <SkeletonSettingsOverview />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/loading.tsx', SettingsLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonNotificationsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function NotificationsLoading() {
4
+ function NotificationsLoading() {
4
5
  return <SkeletonNotificationsPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/notifications/loading.tsx', NotificationsLoading)
@@ -14,6 +14,7 @@ import {
14
14
  Key,
15
15
  type LucideIcon
16
16
  } from 'lucide-react'
17
+ import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
17
18
 
18
19
  // Icon mapping for settings pages
19
20
  const SETTINGS_ICONS: Record<string, LucideIcon> = {
@@ -89,4 +90,4 @@ function SettingsPage() {
89
90
  )
90
91
  }
91
92
 
92
- export default SettingsPage
93
+ export default getTemplateOrDefaultClient('app/dashboard/settings/page.tsx', SettingsPage)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonPasswordPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function PasswordLoading() {
4
+ function PasswordLoading() {
4
5
  return <SkeletonPasswordPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/password/loading.tsx', PasswordLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonPlansPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function PlansLoading() {
4
+ function PlansLoading() {
4
5
  return <SkeletonPlansPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/plans/loading.tsx', PlansLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonProfileForm } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function ProfileLoading() {
4
+ function ProfileLoading() {
4
5
  return <SkeletonProfileForm />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/profile/loading.tsx', ProfileLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonSecurityPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function SecurityLoading() {
4
+ function SecurityLoading() {
4
5
  return <SkeletonSecurityPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/security/loading.tsx', SecurityLoading)
@@ -1,5 +1,8 @@
1
1
  import { SkeletonTeamsPage } from '@nextsparkjs/core/components/ui/skeleton-settings'
2
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
2
3
 
3
- export default function TeamsLoading() {
4
+ function TeamsLoading() {
4
5
  return <SkeletonTeamsPage />
5
6
  }
7
+
8
+ export default getTemplateOrDefault('app/dashboard/settings/teams/loading.tsx', TeamsLoading)
@@ -4,6 +4,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@nextsparkjs/core/comp
4
4
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nextsparkjs/core/components/ui/card'
5
5
  // Use PermissionService which reads from the build-time generated registry
6
6
  import { PermissionService } from '@nextsparkjs/core/lib/services/permission.service'
7
+ import { getTemplateOrDefault } from '@nextsparkjs/core/lib/template-resolver'
7
8
 
8
9
  /**
9
10
  * Team Permissions Page
@@ -11,7 +12,7 @@ import { PermissionService } from '@nextsparkjs/core/lib/services/permission.ser
11
12
  * Displays a visual permissions matrix showing what each team role can do.
12
13
  * Organized by categories with tabs for easy navigation.
13
14
  */
14
- export default function TeamPermissionsPage() {
15
+ function TeamPermissionsPage() {
15
16
  const t = useTranslations('permissions')
16
17
 
17
18
  // Get all unique categories from registry
@@ -90,3 +91,5 @@ function RoleCard({ role }: { role: 'owner' | 'admin' | 'member' | 'viewer' }) {
90
91
  </div>
91
92
  )
92
93
  }
94
+
95
+ export default getTemplateOrDefault('app/dashboard/settings/teams/permissions/page.tsx', TeamPermissionsPage)