@digilogiclabs/create-saas-app 2.7.0 → 2.7.2

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 (118) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/generators/template-generator.d.ts.map +1 -1
  3. package/dist/generators/template-generator.js +18 -12
  4. package/dist/generators/template-generator.js.map +1 -1
  5. package/dist/templates/shared/auth/firebase/web/src/lib/auth-session.ts +25 -0
  6. package/dist/templates/shared/auth/keycloak/web/src/lib/auth-session.ts +24 -0
  7. package/dist/templates/shared/auth/supabase/web/src/lib/auth-session.ts +37 -0
  8. package/dist/templates/shared/config/web/next.config.mjs +1 -0
  9. package/dist/templates/shared/contact/web/{app → src/app}/api/contact/route.ts +4 -4
  10. package/{src/templates/shared/database/supabase/web → dist/templates/shared/database/supabase/web/src}/lib/supabase/server.ts +1 -1
  11. package/dist/templates/shared/loading/web/src/app/loading.tsx +9 -0
  12. package/dist/templates/shared/payments/web/{app → src/app}/api/webhooks/stripe/route.ts +1 -1
  13. package/{src/templates/shared/security/web → dist/templates/shared/security/web/src}/lib/api-security.ts +7 -3
  14. package/dist/templates/web/ai-platform/template/middleware.ts +55 -55
  15. package/dist/templates/web/ai-platform/template/src/lib/supabase/server.ts +27 -27
  16. package/dist/templates/web/iot-dashboard/template/middleware.ts +56 -56
  17. package/dist/templates/web/iot-dashboard/template/src/lib/supabase/server.ts +27 -27
  18. package/dist/templates/web/marketplace/template/middleware.ts +56 -56
  19. package/dist/templates/web/marketplace/template/src/lib/supabase/server.ts +27 -27
  20. package/dist/templates/web/micro-saas/template/middleware.ts +1 -1
  21. package/dist/templates/web/micro-saas/template/src/lib/supabase/server.ts +29 -29
  22. package/dist/templates/web/ui-auth-ai/template/package.json +1 -3
  23. package/dist/templates/web/ui-auth-ai/template/src/app/error.tsx +75 -0
  24. package/dist/templates/web/ui-auth-ai/template/src/app/loading.tsx +39 -0
  25. package/dist/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +4 -7
  26. package/package.json +1 -1
  27. package/src/templates/shared/auth/firebase/web/src/lib/auth-session.ts +25 -0
  28. package/src/templates/shared/auth/keycloak/web/src/lib/auth-session.ts +24 -0
  29. package/src/templates/shared/auth/supabase/web/src/lib/auth-session.ts +37 -0
  30. package/src/templates/shared/config/web/next.config.mjs +1 -0
  31. package/src/templates/shared/contact/web/{app → src/app}/api/contact/route.ts +4 -4
  32. package/{dist/templates/shared/database/supabase/web → src/templates/shared/database/supabase/web/src}/lib/supabase/server.ts +1 -1
  33. package/src/templates/shared/loading/web/src/app/loading.tsx +9 -0
  34. package/src/templates/shared/payments/web/{app → src/app}/api/webhooks/stripe/route.ts +1 -1
  35. package/{dist/templates/shared/security/web → src/templates/shared/security/web/src}/lib/api-security.ts +7 -3
  36. package/src/templates/web/ai-platform/template/middleware.ts +55 -55
  37. package/src/templates/web/ai-platform/template/src/lib/supabase/server.ts +27 -27
  38. package/src/templates/web/iot-dashboard/template/middleware.ts +56 -56
  39. package/src/templates/web/iot-dashboard/template/src/lib/supabase/server.ts +27 -27
  40. package/src/templates/web/marketplace/template/middleware.ts +56 -56
  41. package/src/templates/web/marketplace/template/src/lib/supabase/server.ts +27 -27
  42. package/src/templates/web/micro-saas/template/middleware.ts +1 -1
  43. package/src/templates/web/micro-saas/template/src/lib/supabase/server.ts +29 -29
  44. package/src/templates/web/ui-auth-ai/template/package.json +1 -3
  45. package/src/templates/web/ui-auth-ai/template/src/app/error.tsx +75 -0
  46. package/src/templates/web/ui-auth-ai/template/src/app/loading.tsx +39 -0
  47. package/src/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +4 -7
  48. package/dist/templates/shared/loading/web/app/loading.tsx +0 -5
  49. package/dist/templates/web/base/template.backup/.env.example +0 -15
  50. package/dist/templates/web/ui-auth/template.backup/.env.example +0 -15
  51. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.backup +0 -391
  52. package/dist/templates/web/ui-auth-payments-ai/template/src/app/page.tsx.bak +0 -391
  53. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.backup +0 -391
  54. package/dist/templates/web/ui-auth-payments-audio/template/src/app/page.tsx.bak +0 -391
  55. package/dist/templates/web/ui-only/template.backup/.env.example +0 -15
  56. package/src/templates/shared/loading/web/app/loading.tsx +0 -5
  57. /package/dist/templates/shared/admin/web/{app → src/app}/admin/layout.tsx +0 -0
  58. /package/dist/templates/shared/audit/web/{lib → src/lib}/audit.ts +0 -0
  59. /package/dist/templates/shared/auth/keycloak/web/{app → src/app}/api/auth/federated-logout/route.ts +0 -0
  60. /package/dist/templates/shared/beta/web/{app → src/app}/api/beta-settings/route.ts +0 -0
  61. /package/dist/templates/shared/beta/web/{app → src/app}/api/validate-beta-code/route.ts +0 -0
  62. /package/dist/templates/shared/beta/web/{lib → src/lib}/beta/settings.ts +0 -0
  63. /package/dist/templates/shared/cache/web/{lib → src/lib}/cache.ts +0 -0
  64. /package/dist/templates/shared/config/web/{lib → src/lib}/config.ts +0 -0
  65. /package/dist/templates/shared/contact/web/{app → src/app}/contact/page.tsx +0 -0
  66. /package/dist/templates/shared/database/postgresql/web/{lib → src/lib}/db/drizzle.ts +0 -0
  67. /package/dist/templates/shared/database/postgresql/web/{lib → src/lib}/db/schema.ts +0 -0
  68. /package/dist/templates/shared/database/supabase/web/{lib → src/lib}/supabase/client.ts +0 -0
  69. /package/dist/templates/shared/database/supabase/web/{lib → src/lib}/supabase/service.ts +0 -0
  70. /package/dist/templates/shared/email/web/{lib → src/lib}/email/branding.ts +0 -0
  71. /package/dist/templates/shared/email/web/{lib → src/lib}/email/client.ts +0 -0
  72. /package/dist/templates/shared/error-pages/web/{app → src/app}/error.tsx +0 -0
  73. /package/dist/templates/shared/error-pages/web/{app → src/app}/global-error.tsx +0 -0
  74. /package/dist/templates/shared/error-pages/web/{app → src/app}/not-found.tsx +0 -0
  75. /package/dist/templates/shared/health/web/{app → src/app}/api/health/route.ts +0 -0
  76. /package/dist/templates/shared/legal/web/{app → src/app}/(legal)/privacy/page.tsx +0 -0
  77. /package/dist/templates/shared/legal/web/{app → src/app}/(legal)/terms/page.tsx +0 -0
  78. /package/dist/templates/shared/legal/web/{lib → src/lib}/legal-config.ts +0 -0
  79. /package/dist/templates/shared/observability/web/{lib → src/lib}/observability.ts +0 -0
  80. /package/dist/templates/shared/platform/web/{lib → src/lib}/platform.ts +0 -0
  81. /package/dist/templates/shared/redis/web/{lib → src/lib}/rate-limit-store.ts +0 -0
  82. /package/dist/templates/shared/redis/web/{lib → src/lib}/redis.ts +0 -0
  83. /package/dist/templates/shared/seo/web/{app → src/app}/api/og/route.tsx +0 -0
  84. /package/dist/templates/shared/seo/web/{app → src/app}/robots.ts +0 -0
  85. /package/dist/templates/shared/seo/web/{app → src/app}/sitemap.ts +0 -0
  86. /package/dist/templates/shared/utils/web/{lib → src/lib}/api-response.ts +0 -0
  87. /package/dist/templates/shared/utils/web/{lib → src/lib}/utils.ts +0 -0
  88. /package/src/templates/shared/admin/web/{app → src/app}/admin/layout.tsx +0 -0
  89. /package/src/templates/shared/audit/web/{lib → src/lib}/audit.ts +0 -0
  90. /package/src/templates/shared/auth/keycloak/web/{app → src/app}/api/auth/federated-logout/route.ts +0 -0
  91. /package/src/templates/shared/beta/web/{app → src/app}/api/beta-settings/route.ts +0 -0
  92. /package/src/templates/shared/beta/web/{app → src/app}/api/validate-beta-code/route.ts +0 -0
  93. /package/src/templates/shared/beta/web/{lib → src/lib}/beta/settings.ts +0 -0
  94. /package/src/templates/shared/cache/web/{lib → src/lib}/cache.ts +0 -0
  95. /package/src/templates/shared/config/web/{lib → src/lib}/config.ts +0 -0
  96. /package/src/templates/shared/contact/web/{app → src/app}/contact/page.tsx +0 -0
  97. /package/src/templates/shared/database/postgresql/web/{lib → src/lib}/db/drizzle.ts +0 -0
  98. /package/src/templates/shared/database/postgresql/web/{lib → src/lib}/db/schema.ts +0 -0
  99. /package/src/templates/shared/database/supabase/web/{lib → src/lib}/supabase/client.ts +0 -0
  100. /package/src/templates/shared/database/supabase/web/{lib → src/lib}/supabase/service.ts +0 -0
  101. /package/src/templates/shared/email/web/{lib → src/lib}/email/branding.ts +0 -0
  102. /package/src/templates/shared/email/web/{lib → src/lib}/email/client.ts +0 -0
  103. /package/src/templates/shared/error-pages/web/{app → src/app}/error.tsx +0 -0
  104. /package/src/templates/shared/error-pages/web/{app → src/app}/global-error.tsx +0 -0
  105. /package/src/templates/shared/error-pages/web/{app → src/app}/not-found.tsx +0 -0
  106. /package/src/templates/shared/health/web/{app → src/app}/api/health/route.ts +0 -0
  107. /package/src/templates/shared/legal/web/{app → src/app}/(legal)/privacy/page.tsx +0 -0
  108. /package/src/templates/shared/legal/web/{app → src/app}/(legal)/terms/page.tsx +0 -0
  109. /package/src/templates/shared/legal/web/{lib → src/lib}/legal-config.ts +0 -0
  110. /package/src/templates/shared/observability/web/{lib → src/lib}/observability.ts +0 -0
  111. /package/src/templates/shared/platform/web/{lib → src/lib}/platform.ts +0 -0
  112. /package/src/templates/shared/redis/web/{lib → src/lib}/rate-limit-store.ts +0 -0
  113. /package/src/templates/shared/redis/web/{lib → src/lib}/redis.ts +0 -0
  114. /package/src/templates/shared/seo/web/{app → src/app}/api/og/route.tsx +0 -0
  115. /package/src/templates/shared/seo/web/{app → src/app}/robots.ts +0 -0
  116. /package/src/templates/shared/seo/web/{app → src/app}/sitemap.ts +0 -0
  117. /package/src/templates/shared/utils/web/{lib → src/lib}/api-response.ts +0 -0
  118. /package/src/templates/shared/utils/web/{lib → src/lib}/utils.ts +0 -0
@@ -1,56 +1,56 @@
1
- import { createServerClient } from '@supabase/ssr'
2
- import { NextResponse, type NextRequest } from 'next/server'
3
-
4
- export async function middleware(request: NextRequest) {
5
- let supabaseResponse = NextResponse.next({
6
- request,
7
- })
8
-
9
- const supabase = createServerClient(
10
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
11
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
12
- {
13
- cookies: {
14
- getAll() {
15
- return request.cookies.getAll()
16
- },
17
- setAll(cookiesToSet) {
18
- cookiesToSet.forEach(({ name, value }) =>
19
- request.cookies.set(name, value)
20
- )
21
- supabaseResponse = NextResponse.next({
22
- request,
23
- })
24
- cookiesToSet.forEach(({ name, value, options }) =>
25
- supabaseResponse.cookies.set(name, value, options)
26
- )
27
- },
28
- },
29
- }
30
- )
31
-
32
- const {
33
- data: { user },
34
- } = await supabase.auth.getUser()
35
-
36
- // Redirect to login if accessing protected route without auth
37
- if (
38
- !user &&
39
- (request.nextUrl.pathname.startsWith('/dashboard') ||
40
- request.nextUrl.pathname.startsWith('/devices') ||
41
- request.nextUrl.pathname.startsWith('/analytics') ||
42
- request.nextUrl.pathname.startsWith('/alerts'))
43
- ) {
44
- const url = request.nextUrl.clone()
45
- url.pathname = '/login'
46
- return NextResponse.redirect(url)
47
- }
48
-
49
- return supabaseResponse
50
- }
51
-
52
- export const config = {
53
- matcher: [
54
- '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
55
- ],
56
- }
1
+ import { createServerClient } from '@supabase/ssr'
2
+ import { NextResponse, type NextRequest } from 'next/server'
3
+
4
+ export async function middleware(request: NextRequest) {
5
+ let supabaseResponse = NextResponse.next({
6
+ request,
7
+ })
8
+
9
+ const supabase = createServerClient(
10
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
11
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
12
+ {
13
+ cookies: {
14
+ getAll() {
15
+ return request.cookies.getAll()
16
+ },
17
+ setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
18
+ cookiesToSet.forEach(({ name, value }) =>
19
+ request.cookies.set(name, value)
20
+ )
21
+ supabaseResponse = NextResponse.next({
22
+ request,
23
+ })
24
+ cookiesToSet.forEach(({ name, value, options }) =>
25
+ supabaseResponse.cookies.set(name, value, options)
26
+ )
27
+ },
28
+ },
29
+ }
30
+ )
31
+
32
+ const {
33
+ data: { user },
34
+ } = await supabase.auth.getUser()
35
+
36
+ // Redirect to login if accessing protected route without auth
37
+ if (
38
+ !user &&
39
+ (request.nextUrl.pathname.startsWith('/dashboard') ||
40
+ request.nextUrl.pathname.startsWith('/devices') ||
41
+ request.nextUrl.pathname.startsWith('/analytics') ||
42
+ request.nextUrl.pathname.startsWith('/alerts'))
43
+ ) {
44
+ const url = request.nextUrl.clone()
45
+ url.pathname = '/login'
46
+ return NextResponse.redirect(url)
47
+ }
48
+
49
+ return supabaseResponse
50
+ }
51
+
52
+ export const config = {
53
+ matcher: [
54
+ '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
55
+ ],
56
+ }
@@ -1,27 +1,27 @@
1
- import { createServerClient } from '@supabase/ssr'
2
- import { cookies } from 'next/headers'
3
-
4
- export async function createClient() {
5
- const cookieStore = await cookies()
6
-
7
- return createServerClient(
8
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
9
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
10
- {
11
- cookies: {
12
- getAll() {
13
- return cookieStore.getAll()
14
- },
15
- setAll(cookiesToSet) {
16
- try {
17
- cookiesToSet.forEach(({ name, value, options }) =>
18
- cookieStore.set(name, value, options)
19
- )
20
- } catch {
21
- // Server Component context
22
- }
23
- },
24
- },
25
- }
26
- )
27
- }
1
+ import { createServerClient } from '@supabase/ssr'
2
+ import { cookies } from 'next/headers'
3
+
4
+ export async function createClient() {
5
+ const cookieStore = await cookies()
6
+
7
+ return createServerClient(
8
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
9
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
10
+ {
11
+ cookies: {
12
+ getAll() {
13
+ return cookieStore.getAll()
14
+ },
15
+ setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
16
+ try {
17
+ cookiesToSet.forEach(({ name, value, options }) =>
18
+ cookieStore.set(name, value, options)
19
+ )
20
+ } catch {
21
+ // Server Component context
22
+ }
23
+ },
24
+ },
25
+ }
26
+ )
27
+ }
@@ -1,56 +1,56 @@
1
- import { createServerClient } from '@supabase/ssr'
2
- import { NextResponse, type NextRequest } from 'next/server'
3
-
4
- export async function middleware(request: NextRequest) {
5
- let supabaseResponse = NextResponse.next({
6
- request,
7
- })
8
-
9
- const supabase = createServerClient(
10
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
11
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
12
- {
13
- cookies: {
14
- getAll() {
15
- return request.cookies.getAll()
16
- },
17
- setAll(cookiesToSet) {
18
- cookiesToSet.forEach(({ name, value }) =>
19
- request.cookies.set(name, value)
20
- )
21
- supabaseResponse = NextResponse.next({
22
- request,
23
- })
24
- cookiesToSet.forEach(({ name, value, options }) =>
25
- supabaseResponse.cookies.set(name, value, options)
26
- )
27
- },
28
- },
29
- }
30
- )
31
-
32
- const {
33
- data: { user },
34
- } = await supabase.auth.getUser()
35
-
36
- // Redirect to login if accessing protected route without auth
37
- if (
38
- !user &&
39
- (request.nextUrl.pathname.startsWith('/dashboard') ||
40
- request.nextUrl.pathname.startsWith('/products/new') ||
41
- request.nextUrl.pathname.startsWith('/orders') ||
42
- request.nextUrl.pathname.startsWith('/payouts'))
43
- ) {
44
- const url = request.nextUrl.clone()
45
- url.pathname = '/login'
46
- return NextResponse.redirect(url)
47
- }
48
-
49
- return supabaseResponse
50
- }
51
-
52
- export const config = {
53
- matcher: [
54
- '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
55
- ],
56
- }
1
+ import { createServerClient } from '@supabase/ssr'
2
+ import { NextResponse, type NextRequest } from 'next/server'
3
+
4
+ export async function middleware(request: NextRequest) {
5
+ let supabaseResponse = NextResponse.next({
6
+ request,
7
+ })
8
+
9
+ const supabase = createServerClient(
10
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
11
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
12
+ {
13
+ cookies: {
14
+ getAll() {
15
+ return request.cookies.getAll()
16
+ },
17
+ setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
18
+ cookiesToSet.forEach(({ name, value }) =>
19
+ request.cookies.set(name, value)
20
+ )
21
+ supabaseResponse = NextResponse.next({
22
+ request,
23
+ })
24
+ cookiesToSet.forEach(({ name, value, options }) =>
25
+ supabaseResponse.cookies.set(name, value, options)
26
+ )
27
+ },
28
+ },
29
+ }
30
+ )
31
+
32
+ const {
33
+ data: { user },
34
+ } = await supabase.auth.getUser()
35
+
36
+ // Redirect to login if accessing protected route without auth
37
+ if (
38
+ !user &&
39
+ (request.nextUrl.pathname.startsWith('/dashboard') ||
40
+ request.nextUrl.pathname.startsWith('/products/new') ||
41
+ request.nextUrl.pathname.startsWith('/orders') ||
42
+ request.nextUrl.pathname.startsWith('/payouts'))
43
+ ) {
44
+ const url = request.nextUrl.clone()
45
+ url.pathname = '/login'
46
+ return NextResponse.redirect(url)
47
+ }
48
+
49
+ return supabaseResponse
50
+ }
51
+
52
+ export const config = {
53
+ matcher: [
54
+ '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
55
+ ],
56
+ }
@@ -1,27 +1,27 @@
1
- import { createServerClient } from '@supabase/ssr'
2
- import { cookies } from 'next/headers'
3
-
4
- export async function createClient() {
5
- const cookieStore = await cookies()
6
-
7
- return createServerClient(
8
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
9
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
10
- {
11
- cookies: {
12
- getAll() {
13
- return cookieStore.getAll()
14
- },
15
- setAll(cookiesToSet) {
16
- try {
17
- cookiesToSet.forEach(({ name, value, options }) =>
18
- cookieStore.set(name, value, options)
19
- )
20
- } catch {
21
- // Server Component context
22
- }
23
- },
24
- },
25
- }
26
- )
27
- }
1
+ import { createServerClient } from '@supabase/ssr'
2
+ import { cookies } from 'next/headers'
3
+
4
+ export async function createClient() {
5
+ const cookieStore = await cookies()
6
+
7
+ return createServerClient(
8
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
9
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
10
+ {
11
+ cookies: {
12
+ getAll() {
13
+ return cookieStore.getAll()
14
+ },
15
+ setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
16
+ try {
17
+ cookiesToSet.forEach(({ name, value, options }) =>
18
+ cookieStore.set(name, value, options)
19
+ )
20
+ } catch {
21
+ // Server Component context
22
+ }
23
+ },
24
+ },
25
+ }
26
+ )
27
+ }
@@ -14,7 +14,7 @@ export async function middleware(request: NextRequest) {
14
14
  getAll() {
15
15
  return request.cookies.getAll()
16
16
  },
17
- setAll(cookiesToSet) {
17
+ setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
18
18
  cookiesToSet.forEach(({ name, value }) =>
19
19
  request.cookies.set(name, value)
20
20
  )
@@ -1,29 +1,29 @@
1
- import { createServerClient } from '@supabase/ssr'
2
- import { cookies } from 'next/headers'
3
-
4
- export async function createClient() {
5
- const cookieStore = await cookies()
6
-
7
- return createServerClient(
8
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
9
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
10
- {
11
- cookies: {
12
- getAll() {
13
- return cookieStore.getAll()
14
- },
15
- setAll(cookiesToSet) {
16
- try {
17
- cookiesToSet.forEach(({ name, value, options }) =>
18
- cookieStore.set(name, value, options)
19
- )
20
- } catch {
21
- // The `setAll` method was called from a Server Component.
22
- // This can be ignored if you have middleware refreshing
23
- // user sessions.
24
- }
25
- },
26
- },
27
- }
28
- )
29
- }
1
+ import { createServerClient } from '@supabase/ssr'
2
+ import { cookies } from 'next/headers'
3
+
4
+ export async function createClient() {
5
+ const cookieStore = await cookies()
6
+
7
+ return createServerClient(
8
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
9
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
10
+ {
11
+ cookies: {
12
+ getAll() {
13
+ return cookieStore.getAll()
14
+ },
15
+ setAll(cookiesToSet: Array<{ name: string; value: string; options?: Record<string, unknown> }>) {
16
+ try {
17
+ cookiesToSet.forEach(({ name, value, options }) =>
18
+ cookieStore.set(name, value, options)
19
+ )
20
+ } catch {
21
+ // The `setAll` method was called from a Server Component.
22
+ // This can be ignored if you have middleware refreshing
23
+ // user sessions.
24
+ }
25
+ },
26
+ },
27
+ }
28
+ )
29
+ }
@@ -18,9 +18,7 @@
18
18
  "clsx": "^2.0.0",
19
19
  "tailwindcss": "^3.3.0",
20
20
  "autoprefixer": "^10.4.16",
21
- "postcss": "^8.4.31",{{#ai.enabled}}
22
- "@digilogiclabs/saas-factory-ai": "^4.0.2",
23
- "@digilogiclabs/saas-factory-ai-types": "^4.0.2"{{/ai.enabled}}
21
+ "postcss": "^8.4.31"
24
22
  },
25
23
  "devDependencies": {
26
24
  "@types/node": "^20.0.0",
@@ -0,0 +1,75 @@
1
+ 'use client'
2
+
3
+ import { useEffect } from 'react'
4
+ import { Button, Card } from '@digilogiclabs/saas-factory-ui'
5
+ import { AlertTriangle, RefreshCw, Home } from 'lucide-react'
6
+ import Link from 'next/link'
7
+
8
+ interface ErrorProps {
9
+ error: Error & { digest?: string }
10
+ reset: () => void
11
+ }
12
+
13
+ export default function Error({ error, reset }: ErrorProps) {
14
+ useEffect(() => {
15
+ console.error('Application error:', error)
16
+ }, [error])
17
+
18
+ return (
19
+ <div className="min-h-screen bg-gradient-to-br from-red-50 to-orange-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center p-4">
20
+ <Card className="p-8 max-w-lg w-full">
21
+ <div className="flex flex-col items-center space-y-6 text-center">
22
+ <div className="w-16 h-16 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center">
23
+ <AlertTriangle className="w-8 h-8 text-red-600 dark:text-red-400" />
24
+ </div>
25
+
26
+ <div>
27
+ <h1 className="text-2xl font-bold text-gray-900 dark:text-white mb-2">
28
+ Something went wrong!
29
+ </h1>
30
+ <p className="text-gray-600 dark:text-gray-300 mb-4">
31
+ We encountered an unexpected error. This has been logged and our team will look into it.
32
+ </p>
33
+
34
+ {process.env.NODE_ENV === 'development' && (
35
+ <details className="mt-4 text-left">
36
+ <summary className="cursor-pointer text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
37
+ Error details (development only)
38
+ </summary>
39
+ <div className="mt-2 p-3 bg-gray-100 dark:bg-gray-800 rounded text-xs font-mono text-gray-700 dark:text-gray-300 overflow-auto max-h-40">
40
+ <div className="mb-2">
41
+ <strong>Message:</strong> {error.message}
42
+ </div>
43
+ {error.digest && (
44
+ <div className="mb-2">
45
+ <strong>Digest:</strong> {error.digest}
46
+ </div>
47
+ )}
48
+ {error.stack && (
49
+ <div>
50
+ <strong>Stack:</strong>
51
+ <pre className="whitespace-pre-wrap mt-1">{error.stack}</pre>
52
+ </div>
53
+ )}
54
+ </div>
55
+ </details>
56
+ )}
57
+ </div>
58
+
59
+ <div className="flex flex-col sm:flex-row gap-3 w-full">
60
+ <Button onClick={reset} className="flex-1" size="lg">
61
+ <RefreshCw className="w-4 h-4 mr-2" />
62
+ Try again
63
+ </Button>
64
+ <Link href="/" className="flex-1">
65
+ <Button variant="outline" className="w-full" size="lg">
66
+ <Home className="w-4 h-4 mr-2" />
67
+ Go home
68
+ </Button>
69
+ </Link>
70
+ </div>
71
+ </div>
72
+ </Card>
73
+ </div>
74
+ )
75
+ }
@@ -0,0 +1,39 @@
1
+ import { Card, SkeletonCard, SkeletonText } from '@digilogiclabs/saas-factory-ui'
2
+
3
+ export default function Loading() {
4
+ return (
5
+ <div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800">
6
+ <div className="max-w-4xl mx-auto px-4 py-16">
7
+ {/* Header skeleton */}
8
+ <div className="flex justify-end mb-8">
9
+ <SkeletonText className="h-8 w-24" />
10
+ </div>
11
+
12
+ {/* Hero skeleton */}
13
+ <div className="text-center mb-16">
14
+ <SkeletonText className="h-6 w-32 mx-auto mb-6" />
15
+ <SkeletonText className="h-12 w-64 mx-auto mb-6" />
16
+ <SkeletonText className="h-6 w-96 mx-auto mb-8" />
17
+ </div>
18
+
19
+ {/* Feature cards skeleton */}
20
+ <div className="grid md:grid-cols-3 gap-6 mb-16">
21
+ {Array.from({ length: 3 }).map((_, i) => (
22
+ <SkeletonCard key={i} />
23
+ ))}
24
+ </div>
25
+
26
+ {/* CTA skeleton */}
27
+ <Card className="p-8">
28
+ <div className="flex flex-col items-center space-y-4">
29
+ <div className="relative">
30
+ <div className="w-12 h-12 border-4 border-gray-200 dark:border-gray-700 rounded-full animate-spin"></div>
31
+ <div className="absolute top-0 left-0 w-12 h-12 border-4 border-blue-600 border-t-transparent rounded-full animate-spin"></div>
32
+ </div>
33
+ <p className="text-sm text-gray-600 dark:text-gray-300">Loading...</p>
34
+ </div>
35
+ </Card>
36
+ </div>
37
+ </div>
38
+ )
39
+ }
@@ -2,7 +2,6 @@
2
2
 
3
3
  import React from 'react'
4
4
  import { ThemeProvider } from 'next-themes'
5
- import { DLLProvider } from '@digilogiclabs/app-sdk'
6
5
  import { Toaster } from '@digilogiclabs/saas-factory-ui'
7
6
  import { AppThemeProvider } from './theme-provider'
8
7
 
@@ -19,12 +18,10 @@ export function AppProviders({ children }: AppProvidersProps) {
19
18
  disableTransitionOnChange
20
19
  storageKey="{{packageName}}-theme"
21
20
  >
22
- <DLLProvider>
23
- <AppThemeProvider themeColor="{{themeColor}}">
24
- {children}
25
- <Toaster />
26
- </AppThemeProvider>
27
- </DLLProvider>
21
+ <AppThemeProvider themeColor="{{themeColor}}">
22
+ {children}
23
+ <Toaster />
24
+ </AppThemeProvider>
28
25
  </ThemeProvider>
29
26
  )
30
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digilogiclabs/create-saas-app",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "Create modern SaaS applications with DLL Platform - tier-aware scaffolding with platform-core and app-sdk",
5
5
  "main": "dist/cli/index.js",
6
6
  "bin": {
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Auth session adapter for Firebase.
3
+ * Provides a consistent getSession() interface for api-security.ts.
4
+ */
5
+ import 'server-only';
6
+
7
+ type Session = {
8
+ user?: {
9
+ id?: string;
10
+ email?: string | null;
11
+ name?: string | null;
12
+ };
13
+ };
14
+
15
+ export async function getSession(): Promise<Session | null> {
16
+ // Firebase server-side auth is typically handled via admin SDK
17
+ // or by verifying the ID token from cookies.
18
+ // Implement based on your Firebase setup.
19
+ return null;
20
+ }
21
+
22
+ export async function getUser() {
23
+ const session = await getSession();
24
+ return session?.user ?? null;
25
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Auth session adapter for Keycloak (Auth.js).
3
+ * Provides a consistent getSession() interface for api-security.ts.
4
+ */
5
+ import 'server-only';
6
+
7
+ type Session = {
8
+ user?: {
9
+ id?: string;
10
+ email?: string | null;
11
+ name?: string | null;
12
+ roles?: string[];
13
+ };
14
+ };
15
+
16
+ export async function getSession(): Promise<Session | null> {
17
+ const { auth } = await import('@/auth');
18
+ return auth();
19
+ }
20
+
21
+ export async function getUser() {
22
+ const session = await getSession();
23
+ return session?.user ?? null;
24
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Auth session adapter for Supabase.
3
+ * Provides a consistent getSession() interface for api-security.ts.
4
+ */
5
+ import 'server-only';
6
+ import { createClient } from '@/lib/supabase/server';
7
+
8
+ type Session = {
9
+ user?: {
10
+ id?: string;
11
+ email?: string | null;
12
+ name?: string | null;
13
+ };
14
+ };
15
+
16
+ export async function getSession(): Promise<Session | null> {
17
+ const supabase = await createClient();
18
+ const {
19
+ data: { user },
20
+ error,
21
+ } = await supabase.auth.getUser();
22
+
23
+ if (error || !user) return null;
24
+
25
+ return {
26
+ user: {
27
+ id: user.id,
28
+ email: user.email ?? null,
29
+ name: user.user_metadata?.name ?? user.user_metadata?.full_name ?? null,
30
+ },
31
+ };
32
+ }
33
+
34
+ export async function getUser() {
35
+ const session = await getSession();
36
+ return session?.user ?? null;
37
+ }
@@ -48,6 +48,7 @@ const nextConfig = {
48
48
  // Stub main barrel only — subpaths like /auth and /security-headers
49
49
  // are Edge-safe and must NOT be stubbed.
50
50
  '@digilogiclabs/platform-core$': false,
51
+ '@digilogiclabs/app-sdk$': false,
51
52
  'ioredis$': false,
52
53
  'pg$': false,
53
54
  'nodemailer$': false,