@victusvinceere/saas-core 0.1.0

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 (64) hide show
  1. package/dist/auth/index.d.mts +40 -0
  2. package/dist/auth/index.d.ts +40 -0
  3. package/dist/auth/index.js +147 -0
  4. package/dist/auth/index.js.map +1 -0
  5. package/dist/auth/index.mjs +111 -0
  6. package/dist/auth/index.mjs.map +1 -0
  7. package/dist/authorization/index.d.mts +78 -0
  8. package/dist/authorization/index.d.ts +78 -0
  9. package/dist/authorization/index.js +137 -0
  10. package/dist/authorization/index.js.map +1 -0
  11. package/dist/authorization/index.mjs +104 -0
  12. package/dist/authorization/index.mjs.map +1 -0
  13. package/dist/components/auth/index.d.mts +26 -0
  14. package/dist/components/auth/index.d.ts +26 -0
  15. package/dist/components/auth/index.js +733 -0
  16. package/dist/components/auth/index.js.map +1 -0
  17. package/dist/components/auth/index.mjs +696 -0
  18. package/dist/components/auth/index.mjs.map +1 -0
  19. package/dist/components/dashboard/index.d.mts +32 -0
  20. package/dist/components/dashboard/index.d.ts +32 -0
  21. package/dist/components/dashboard/index.js +440 -0
  22. package/dist/components/dashboard/index.js.map +1 -0
  23. package/dist/components/dashboard/index.mjs +401 -0
  24. package/dist/components/dashboard/index.mjs.map +1 -0
  25. package/dist/components/ui/index.d.mts +351 -0
  26. package/dist/components/ui/index.d.ts +351 -0
  27. package/dist/components/ui/index.js +14342 -0
  28. package/dist/components/ui/index.js.map +1 -0
  29. package/dist/components/ui/index.mjs +14173 -0
  30. package/dist/components/ui/index.mjs.map +1 -0
  31. package/dist/config/index.d.mts +45 -0
  32. package/dist/config/index.d.ts +45 -0
  33. package/dist/config/index.js +71 -0
  34. package/dist/config/index.js.map +1 -0
  35. package/dist/config/index.mjs +44 -0
  36. package/dist/config/index.mjs.map +1 -0
  37. package/dist/hooks/index.d.mts +20 -0
  38. package/dist/hooks/index.d.ts +20 -0
  39. package/dist/hooks/index.js +103 -0
  40. package/dist/hooks/index.js.map +1 -0
  41. package/dist/hooks/index.mjs +65 -0
  42. package/dist/hooks/index.mjs.map +1 -0
  43. package/dist/index.d.mts +21 -0
  44. package/dist/index.d.ts +21 -0
  45. package/dist/index.js +459 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/index.mjs +401 -0
  48. package/dist/index.mjs.map +1 -0
  49. package/dist/prisma/index.d.mts +11 -0
  50. package/dist/prisma/index.d.ts +11 -0
  51. package/dist/prisma/index.js +46 -0
  52. package/dist/prisma/index.js.map +1 -0
  53. package/dist/prisma/index.mjs +20 -0
  54. package/dist/prisma/index.mjs.map +1 -0
  55. package/dist/providers/index.d.mts +37 -0
  56. package/dist/providers/index.d.ts +37 -0
  57. package/dist/providers/index.js +97 -0
  58. package/dist/providers/index.js.map +1 -0
  59. package/dist/providers/index.mjs +69 -0
  60. package/dist/providers/index.mjs.map +1 -0
  61. package/dist/sidebar-ttX_iZ40.d.mts +22 -0
  62. package/dist/sidebar-ttX_iZ40.d.ts +22 -0
  63. package/package.json +122 -0
  64. package/prisma/schema.prisma +106 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,401 @@
1
+ "use client";
2
+
3
+ // src/auth/create-auth-config.ts
4
+ import Google from "next-auth/providers/google";
5
+ import Resend from "next-auth/providers/resend";
6
+ import GitHub from "next-auth/providers/github";
7
+ import Credentials from "next-auth/providers/credentials";
8
+ function createProviders(options) {
9
+ const providers = [];
10
+ for (const provider of options.providers) {
11
+ switch (provider) {
12
+ case "google":
13
+ providers.push(
14
+ Google({
15
+ clientId: process.env.GOOGLE_CLIENT_ID,
16
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET
17
+ })
18
+ );
19
+ break;
20
+ case "github":
21
+ providers.push(
22
+ GitHub({
23
+ clientId: process.env.GITHUB_CLIENT_ID,
24
+ clientSecret: process.env.GITHUB_CLIENT_SECRET
25
+ })
26
+ );
27
+ break;
28
+ case "email":
29
+ providers.push(
30
+ Resend({
31
+ apiKey: process.env.AUTH_RESEND_KEY,
32
+ from: options.email?.from || process.env.EMAIL_FROM || "no-reply@example.com"
33
+ })
34
+ );
35
+ break;
36
+ case "credentials":
37
+ if (options.credentials?.authorize) {
38
+ providers.push(
39
+ Credentials({
40
+ credentials: {
41
+ email: { label: "Email", type: "email" },
42
+ password: { label: "Password", type: "password" }
43
+ },
44
+ authorize: async (credentials) => {
45
+ if (!credentials?.email || !credentials?.password) {
46
+ return null;
47
+ }
48
+ return options.credentials.authorize(credentials);
49
+ }
50
+ })
51
+ );
52
+ }
53
+ break;
54
+ }
55
+ }
56
+ return providers;
57
+ }
58
+ function createAuthConfig(options) {
59
+ return {
60
+ adapter: options.adapter,
61
+ session: {
62
+ strategy: options.session?.strategy || "jwt",
63
+ maxAge: options.session?.maxAge || 30 * 24 * 60 * 60
64
+ // 30 days
65
+ },
66
+ providers: createProviders(options),
67
+ pages: {
68
+ signIn: options.pages?.signIn || "/login",
69
+ error: options.pages?.error || "/auth-error",
70
+ verifyRequest: options.pages?.verifyRequest || "/verify-request",
71
+ newUser: options.pages?.newUser
72
+ },
73
+ callbacks: {
74
+ async jwt({ token, user, trigger }) {
75
+ if (user) {
76
+ token.id = user.id;
77
+ if (options.callbacks?.getUserRole) {
78
+ token.role = await options.callbacks.getUserRole(user.id);
79
+ } else {
80
+ token.role = "USER";
81
+ }
82
+ }
83
+ if (trigger === "update" && token.id && options.callbacks?.getUserRole) {
84
+ token.role = await options.callbacks.getUserRole(token.id);
85
+ }
86
+ return token;
87
+ },
88
+ session({ session, token }) {
89
+ if (session.user && token.id) {
90
+ session.user.id = token.id;
91
+ session.user.role = token.role;
92
+ }
93
+ return session;
94
+ }
95
+ },
96
+ events: {
97
+ async createUser({ user }) {
98
+ if (options.callbacks?.onUserCreated && user.email) {
99
+ await options.callbacks.onUserCreated({
100
+ id: user.id,
101
+ email: user.email
102
+ });
103
+ }
104
+ }
105
+ }
106
+ };
107
+ }
108
+
109
+ // src/authorization/index.ts
110
+ import { NextResponse } from "next/server";
111
+ var DEFAULT_ROLE_HIERARCHY = ["USER", "MODERATOR", "ADMIN", "SUPER_ADMIN"];
112
+ var config = {
113
+ roleHierarchy: DEFAULT_ROLE_HIERARCHY,
114
+ permissions: {}
115
+ };
116
+ function configureAuthorization(options) {
117
+ config = { ...config, ...options };
118
+ }
119
+ function hasMinRole(userRole, minRole) {
120
+ const hierarchy = config.roleHierarchy || DEFAULT_ROLE_HIERARCHY;
121
+ const userLevel = hierarchy.indexOf(userRole);
122
+ const minLevel = hierarchy.indexOf(minRole);
123
+ if (userLevel === -1 || minLevel === -1) {
124
+ return false;
125
+ }
126
+ return userLevel >= minLevel;
127
+ }
128
+ function hasRole(userRole, allowedRoles) {
129
+ return allowedRoles.includes(userRole);
130
+ }
131
+ function isAdmin(role) {
132
+ return hasMinRole(role, "ADMIN");
133
+ }
134
+ function isSuperAdmin(role) {
135
+ return role === "SUPER_ADMIN";
136
+ }
137
+ function isModerator(role) {
138
+ return hasMinRole(role, "MODERATOR");
139
+ }
140
+ function hasPermission(userRole, permission) {
141
+ const permissions = config.permissions || {};
142
+ const allowedRoles = permissions[permission];
143
+ if (!allowedRoles) {
144
+ return false;
145
+ }
146
+ return allowedRoles.includes(userRole);
147
+ }
148
+ var PERMISSIONS = {
149
+ // User management
150
+ "users:read": ["MODERATOR", "ADMIN", "SUPER_ADMIN"],
151
+ "users:update": ["ADMIN", "SUPER_ADMIN"],
152
+ "users:delete": ["SUPER_ADMIN"],
153
+ "users:updateRole": ["SUPER_ADMIN"],
154
+ // Content management
155
+ "posts:create": ["MODERATOR", "ADMIN", "SUPER_ADMIN"],
156
+ "posts:update": ["MODERATOR", "ADMIN", "SUPER_ADMIN"],
157
+ "posts:delete": ["ADMIN", "SUPER_ADMIN"],
158
+ "posts:publish": ["ADMIN", "SUPER_ADMIN"],
159
+ // Admin panel access
160
+ "admin:access": ["ADMIN", "SUPER_ADMIN"],
161
+ "admin:settings": ["SUPER_ADMIN"],
162
+ // Subscription management
163
+ "subscriptions:read": ["ADMIN", "SUPER_ADMIN"],
164
+ "subscriptions:manage": ["SUPER_ADMIN"]
165
+ };
166
+ async function withRole(options) {
167
+ const session = await options.getSession();
168
+ if (!session?.user?.id) {
169
+ return {
170
+ authorized: false,
171
+ response: NextResponse.json({ error: "Unauthorized" }, { status: 401 }),
172
+ session: null
173
+ };
174
+ }
175
+ const userRole = session.user.role || "USER";
176
+ if (!hasMinRole(userRole, options.minRole)) {
177
+ return {
178
+ authorized: false,
179
+ response: NextResponse.json({ error: "Forbidden" }, { status: 403 }),
180
+ session
181
+ };
182
+ }
183
+ return {
184
+ authorized: true,
185
+ response: null,
186
+ session
187
+ };
188
+ }
189
+ function createPermissionChecker(permissions) {
190
+ return function checkPermission(userRole, permission) {
191
+ const allowedRoles = permissions[permission];
192
+ if (!allowedRoles) {
193
+ return false;
194
+ }
195
+ return allowedRoles.includes(userRole);
196
+ };
197
+ }
198
+
199
+ // src/config/define-config.ts
200
+ function defineConfig(config2) {
201
+ return {
202
+ app: {
203
+ name: config2.app.name,
204
+ url: config2.app.url || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
205
+ description: config2.app.description || ""
206
+ },
207
+ auth: {
208
+ providers: config2.auth.providers,
209
+ pages: {
210
+ signIn: config2.auth.pages?.signIn || "/login",
211
+ error: config2.auth.pages?.error || "/auth-error",
212
+ verifyRequest: config2.auth.pages?.verifyRequest || "/verify-request",
213
+ ...config2.auth.pages
214
+ }
215
+ },
216
+ dashboard: config2.dashboard,
217
+ features: {
218
+ payments: config2.features?.payments ?? false,
219
+ admin: config2.features?.admin ?? false,
220
+ blog: config2.features?.blog ?? false
221
+ },
222
+ theme: {
223
+ defaultTheme: config2.theme?.defaultTheme || "system",
224
+ enableSystem: config2.theme?.enableSystem ?? true,
225
+ storageKey: config2.theme?.storageKey || "saas-kit-theme"
226
+ }
227
+ };
228
+ }
229
+ function createSiteConfig(config2) {
230
+ return {
231
+ name: config2.app.name,
232
+ description: config2.app.description || "",
233
+ url: config2.app.url || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"
234
+ };
235
+ }
236
+
237
+ // src/providers/session-provider.tsx
238
+ import { SessionProvider as NextAuthSessionProvider } from "next-auth/react";
239
+ import { jsx } from "react/jsx-runtime";
240
+ function SessionProvider({ children }) {
241
+ return /* @__PURE__ */ jsx(NextAuthSessionProvider, { children });
242
+ }
243
+
244
+ // src/providers/theme-provider.tsx
245
+ import { ThemeProvider as NextThemesProvider } from "next-themes";
246
+ import { jsx as jsx2 } from "react/jsx-runtime";
247
+ function ThemeProvider({
248
+ children,
249
+ attribute = "class",
250
+ defaultTheme = "system",
251
+ enableSystem = true,
252
+ disableTransitionOnChange = false,
253
+ storageKey = "saas-kit-theme"
254
+ }) {
255
+ return /* @__PURE__ */ jsx2(
256
+ NextThemesProvider,
257
+ {
258
+ attribute,
259
+ defaultTheme,
260
+ enableSystem,
261
+ disableTransitionOnChange,
262
+ storageKey,
263
+ children
264
+ }
265
+ );
266
+ }
267
+
268
+ // src/providers/saas-kit-provider.tsx
269
+ import { Toaster } from "sonner";
270
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
271
+ function SaasKitProvider({
272
+ children,
273
+ theme = {},
274
+ toaster = {}
275
+ }) {
276
+ return /* @__PURE__ */ jsx3(SessionProvider, { children: /* @__PURE__ */ jsxs(
277
+ ThemeProvider,
278
+ {
279
+ attribute: theme.attribute || "class",
280
+ defaultTheme: theme.defaultTheme || "system",
281
+ enableSystem: theme.enableSystem ?? true,
282
+ disableTransitionOnChange: theme.disableTransitionOnChange ?? false,
283
+ storageKey: theme.storageKey || "saas-kit-theme",
284
+ children: [
285
+ children,
286
+ /* @__PURE__ */ jsx3(
287
+ Toaster,
288
+ {
289
+ position: toaster.position || "bottom-right",
290
+ richColors: toaster.richColors ?? true,
291
+ closeButton: toaster.closeButton ?? true
292
+ }
293
+ )
294
+ ]
295
+ }
296
+ ) });
297
+ }
298
+
299
+ // src/hooks/use-media-query.ts
300
+ import { useEffect, useState } from "react";
301
+ function useMediaQuery(query) {
302
+ const [matches, setMatches] = useState(false);
303
+ useEffect(() => {
304
+ const mediaQuery = window.matchMedia(query);
305
+ setMatches(mediaQuery.matches);
306
+ const handler = (event) => {
307
+ setMatches(event.matches);
308
+ };
309
+ mediaQuery.addEventListener("change", handler);
310
+ return () => {
311
+ mediaQuery.removeEventListener("change", handler);
312
+ };
313
+ }, [query]);
314
+ return matches;
315
+ }
316
+
317
+ // src/hooks/use-mobile.ts
318
+ import * as React from "react";
319
+ var MOBILE_BREAKPOINT = 768;
320
+ function useIsMobile() {
321
+ const [isMobile, setIsMobile] = React.useState(void 0);
322
+ React.useEffect(() => {
323
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
324
+ const onChange = () => {
325
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
326
+ };
327
+ mql.addEventListener("change", onChange);
328
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
329
+ return () => mql.removeEventListener("change", onChange);
330
+ }, []);
331
+ return !!isMobile;
332
+ }
333
+
334
+ // src/hooks/use-current-user.ts
335
+ import { useSession } from "next-auth/react";
336
+ function useCurrentUser() {
337
+ const { data: session, status, update } = useSession();
338
+ const isLoading = status === "loading";
339
+ const isAuthenticated = status === "authenticated";
340
+ const user = session?.user ? {
341
+ id: session.user.id,
342
+ name: session.user.name,
343
+ email: session.user.email,
344
+ image: session.user.image,
345
+ role: session.user.role
346
+ } : null;
347
+ return {
348
+ user,
349
+ isLoading,
350
+ isAuthenticated,
351
+ update: async () => {
352
+ await update();
353
+ }
354
+ };
355
+ }
356
+
357
+ // src/lib/utils.ts
358
+ import { clsx } from "clsx";
359
+ import { twMerge } from "tailwind-merge";
360
+ function cn(...inputs) {
361
+ return twMerge(clsx(inputs));
362
+ }
363
+
364
+ // src/prisma/index.ts
365
+ import { PrismaClient } from "@prisma/client";
366
+ var globalForPrisma = globalThis;
367
+ var prisma = globalForPrisma.prisma ?? new PrismaClient({
368
+ log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"]
369
+ });
370
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
371
+ function createPrismaClient(options) {
372
+ return new PrismaClient({
373
+ log: options?.log ?? (process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"])
374
+ });
375
+ }
376
+ export {
377
+ PERMISSIONS,
378
+ PrismaClient,
379
+ SaasKitProvider,
380
+ SessionProvider,
381
+ ThemeProvider,
382
+ cn,
383
+ configureAuthorization,
384
+ createAuthConfig,
385
+ createPermissionChecker,
386
+ createPrismaClient,
387
+ createSiteConfig,
388
+ defineConfig,
389
+ hasMinRole,
390
+ hasPermission,
391
+ hasRole,
392
+ isAdmin,
393
+ isModerator,
394
+ isSuperAdmin,
395
+ prisma,
396
+ useCurrentUser,
397
+ useIsMobile,
398
+ useMediaQuery,
399
+ withRole
400
+ };
401
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/create-auth-config.ts","../src/authorization/index.ts","../src/config/define-config.ts","../src/providers/session-provider.tsx","../src/providers/theme-provider.tsx","../src/providers/saas-kit-provider.tsx","../src/hooks/use-media-query.ts","../src/hooks/use-mobile.ts","../src/hooks/use-current-user.ts","../src/lib/utils.ts","../src/prisma/index.ts"],"sourcesContent":["import type { NextAuthConfig } from \"next-auth\";\nimport type { Adapter } from \"next-auth/adapters\";\nimport type { Provider } from \"next-auth/providers\";\nimport Google from \"next-auth/providers/google\";\nimport Resend from \"next-auth/providers/resend\";\nimport GitHub from \"next-auth/providers/github\";\nimport Credentials from \"next-auth/providers/credentials\";\n\nexport type AuthProvider = \"google\" | \"github\" | \"email\" | \"credentials\";\n\nexport interface AuthConfigOptions {\n adapter: Adapter;\n providers: AuthProvider[];\n pages?: {\n signIn?: string;\n signOut?: string;\n error?: string;\n verifyRequest?: string;\n newUser?: string;\n };\n callbacks?: {\n onUserCreated?: (user: { id: string; email: string }) => Promise<void>;\n getUserRole?: (userId: string) => Promise<string>;\n };\n session?: {\n strategy?: \"jwt\" | \"database\";\n maxAge?: number;\n };\n credentials?: {\n authorize: (credentials: Record<string, string>) => Promise<{\n id: string;\n email: string;\n name?: string;\n image?: string;\n } | null>;\n };\n email?: {\n from?: string;\n };\n}\n\nfunction createProviders(\n options: AuthConfigOptions\n): Provider[] {\n const providers: Provider[] = [];\n\n for (const provider of options.providers) {\n switch (provider) {\n case \"google\":\n providers.push(\n Google({\n clientId: process.env.GOOGLE_CLIENT_ID!,\n clientSecret: process.env.GOOGLE_CLIENT_SECRET!,\n })\n );\n break;\n case \"github\":\n providers.push(\n GitHub({\n clientId: process.env.GITHUB_CLIENT_ID!,\n clientSecret: process.env.GITHUB_CLIENT_SECRET!,\n })\n );\n break;\n case \"email\":\n providers.push(\n Resend({\n apiKey: process.env.AUTH_RESEND_KEY!,\n from: options.email?.from || process.env.EMAIL_FROM || \"no-reply@example.com\",\n })\n );\n break;\n case \"credentials\":\n if (options.credentials?.authorize) {\n providers.push(\n Credentials({\n credentials: {\n email: { label: \"Email\", type: \"email\" },\n password: { label: \"Password\", type: \"password\" },\n },\n authorize: async (credentials) => {\n if (!credentials?.email || !credentials?.password) {\n return null;\n }\n return options.credentials!.authorize(credentials as Record<string, string>);\n },\n })\n );\n }\n break;\n }\n }\n\n return providers;\n}\n\nexport function createAuthConfig(options: AuthConfigOptions): NextAuthConfig {\n return {\n adapter: options.adapter,\n session: {\n strategy: options.session?.strategy || \"jwt\",\n maxAge: options.session?.maxAge || 30 * 24 * 60 * 60, // 30 days\n },\n providers: createProviders(options),\n pages: {\n signIn: options.pages?.signIn || \"/login\",\n error: options.pages?.error || \"/auth-error\",\n verifyRequest: options.pages?.verifyRequest || \"/verify-request\",\n newUser: options.pages?.newUser,\n },\n callbacks: {\n async jwt({ token, user, trigger }) {\n if (user) {\n token.id = user.id;\n // Get user role from callback or default to USER\n if (options.callbacks?.getUserRole) {\n token.role = await options.callbacks.getUserRole(user.id);\n } else {\n token.role = \"USER\";\n }\n }\n // Refresh role on explicit update trigger\n if (trigger === \"update\" && token.id && options.callbacks?.getUserRole) {\n token.role = await options.callbacks.getUserRole(token.id as string);\n }\n return token;\n },\n session({ session, token }) {\n if (session.user && token.id) {\n session.user.id = token.id as string;\n session.user.role = token.role as string;\n }\n return session;\n },\n },\n events: {\n async createUser({ user }) {\n if (options.callbacks?.onUserCreated && user.email) {\n await options.callbacks.onUserCreated({\n id: user.id!,\n email: user.email,\n });\n }\n },\n },\n };\n}\n","import { NextResponse } from \"next/server\";\n\n// Default role type - can be extended by consumers\nexport type Role = \"USER\" | \"MODERATOR\" | \"ADMIN\" | \"SUPER_ADMIN\";\n\n// Role hierarchy - higher index = more privileges\nconst DEFAULT_ROLE_HIERARCHY: Role[] = [\"USER\", \"MODERATOR\", \"ADMIN\", \"SUPER_ADMIN\"];\n\nexport interface AuthorizationConfig {\n roleHierarchy?: string[];\n permissions?: Record<string, string[]>;\n}\n\nlet config: AuthorizationConfig = {\n roleHierarchy: DEFAULT_ROLE_HIERARCHY,\n permissions: {},\n};\n\n/**\n * Configure the authorization system\n */\nexport function configureAuthorization(options: AuthorizationConfig): void {\n config = { ...config, ...options };\n}\n\n/**\n * Check if a role has at least the minimum required role level\n */\nexport function hasMinRole(userRole: string, minRole: string): boolean {\n const hierarchy = config.roleHierarchy || DEFAULT_ROLE_HIERARCHY;\n const userLevel = hierarchy.indexOf(userRole);\n const minLevel = hierarchy.indexOf(minRole);\n\n if (userLevel === -1 || minLevel === -1) {\n return false;\n }\n\n return userLevel >= minLevel;\n}\n\n/**\n * Check if user has one of the allowed roles\n */\nexport function hasRole(userRole: string, allowedRoles: string[]): boolean {\n return allowedRoles.includes(userRole);\n}\n\n/**\n * Check if user is admin (ADMIN or SUPER_ADMIN)\n */\nexport function isAdmin(role: string): boolean {\n return hasMinRole(role, \"ADMIN\");\n}\n\n/**\n * Check if user is super admin\n */\nexport function isSuperAdmin(role: string): boolean {\n return role === \"SUPER_ADMIN\";\n}\n\n/**\n * Check if user is moderator or higher\n */\nexport function isModerator(role: string): boolean {\n return hasMinRole(role, \"MODERATOR\");\n}\n\n/**\n * Check if user has a specific permission\n */\nexport function hasPermission(userRole: string, permission: string): boolean {\n const permissions = config.permissions || {};\n const allowedRoles = permissions[permission];\n\n if (!allowedRoles) {\n return false;\n }\n\n return allowedRoles.includes(userRole);\n}\n\n/**\n * Default permissions configuration\n */\nexport const PERMISSIONS = {\n // User management\n \"users:read\": [\"MODERATOR\", \"ADMIN\", \"SUPER_ADMIN\"],\n \"users:update\": [\"ADMIN\", \"SUPER_ADMIN\"],\n \"users:delete\": [\"SUPER_ADMIN\"],\n \"users:updateRole\": [\"SUPER_ADMIN\"],\n\n // Content management\n \"posts:create\": [\"MODERATOR\", \"ADMIN\", \"SUPER_ADMIN\"],\n \"posts:update\": [\"MODERATOR\", \"ADMIN\", \"SUPER_ADMIN\"],\n \"posts:delete\": [\"ADMIN\", \"SUPER_ADMIN\"],\n \"posts:publish\": [\"ADMIN\", \"SUPER_ADMIN\"],\n\n // Admin panel access\n \"admin:access\": [\"ADMIN\", \"SUPER_ADMIN\"],\n \"admin:settings\": [\"SUPER_ADMIN\"],\n\n // Subscription management\n \"subscriptions:read\": [\"ADMIN\", \"SUPER_ADMIN\"],\n \"subscriptions:manage\": [\"SUPER_ADMIN\"],\n} as const;\n\nexport type Permission = keyof typeof PERMISSIONS;\n\n/**\n * Higher-order function for protecting API routes\n * Returns unauthorized response if user doesn't have required role\n */\nexport interface WithRoleResult<T = unknown> {\n authorized: boolean;\n response: NextResponse | null;\n session: T | null;\n}\n\nexport interface WithRoleOptions {\n getSession: () => Promise<{ user?: { id?: string; role?: string } } | null>;\n minRole: string;\n}\n\nexport async function withRole(options: WithRoleOptions): Promise<WithRoleResult> {\n const session = await options.getSession();\n\n if (!session?.user?.id) {\n return {\n authorized: false,\n response: NextResponse.json({ error: \"Unauthorized\" }, { status: 401 }),\n session: null,\n };\n }\n\n const userRole = session.user.role || \"USER\";\n\n if (!hasMinRole(userRole, options.minRole)) {\n return {\n authorized: false,\n response: NextResponse.json({ error: \"Forbidden\" }, { status: 403 }),\n session,\n };\n }\n\n return {\n authorized: true,\n response: null,\n session,\n };\n}\n\n/**\n * Create a custom permission checker\n */\nexport function createPermissionChecker(permissions: Record<string, string[]>) {\n return function checkPermission(userRole: string, permission: string): boolean {\n const allowedRoles = permissions[permission];\n if (!allowedRoles) {\n return false;\n }\n return allowedRoles.includes(userRole);\n };\n}\n","import type { AuthProvider } from \"../auth/create-auth-config\";\nimport type { SidebarNavGroup } from \"../components/dashboard/sidebar\";\n\nexport interface SaasKitConfig {\n app: {\n name: string;\n url?: string;\n description?: string;\n };\n auth: {\n providers: AuthProvider[];\n pages?: {\n signIn?: string;\n signOut?: string;\n error?: string;\n verifyRequest?: string;\n newUser?: string;\n };\n };\n dashboard?: {\n navigation?: SidebarNavGroup[];\n };\n features?: {\n payments?: boolean;\n admin?: boolean;\n blog?: boolean;\n };\n theme?: {\n defaultTheme?: \"light\" | \"dark\" | \"system\";\n enableSystem?: boolean;\n storageKey?: string;\n };\n}\n\nexport function defineConfig(config: SaasKitConfig): SaasKitConfig {\n return {\n app: {\n name: config.app.name,\n url: config.app.url || process.env.NEXT_PUBLIC_APP_URL || \"http://localhost:3000\",\n description: config.app.description || \"\",\n },\n auth: {\n providers: config.auth.providers,\n pages: {\n signIn: config.auth.pages?.signIn || \"/login\",\n error: config.auth.pages?.error || \"/auth-error\",\n verifyRequest: config.auth.pages?.verifyRequest || \"/verify-request\",\n ...config.auth.pages,\n },\n },\n dashboard: config.dashboard,\n features: {\n payments: config.features?.payments ?? false,\n admin: config.features?.admin ?? false,\n blog: config.features?.blog ?? false,\n },\n theme: {\n defaultTheme: config.theme?.defaultTheme || \"system\",\n enableSystem: config.theme?.enableSystem ?? true,\n storageKey: config.theme?.storageKey || \"saas-kit-theme\",\n },\n };\n}\n\nexport function createSiteConfig(config: SaasKitConfig) {\n return {\n name: config.app.name,\n description: config.app.description || \"\",\n url: config.app.url || process.env.NEXT_PUBLIC_APP_URL || \"http://localhost:3000\",\n };\n}\n","\"use client\";\n\nimport { SessionProvider as NextAuthSessionProvider } from \"next-auth/react\";\nimport { type ReactNode } from \"react\";\n\nexport interface SessionProviderProps {\n children: ReactNode;\n}\n\nexport function SessionProvider({ children }: SessionProviderProps) {\n return <NextAuthSessionProvider>{children}</NextAuthSessionProvider>;\n}\n","\"use client\";\n\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\nimport type { ThemeProviderProps as NextThemeProviderProps } from \"next-themes\";\nimport { type ReactNode } from \"react\";\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n attribute?: NextThemeProviderProps[\"attribute\"];\n defaultTheme?: string;\n enableSystem?: boolean;\n disableTransitionOnChange?: boolean;\n storageKey?: string;\n}\n\nexport function ThemeProvider({\n children,\n attribute = \"class\",\n defaultTheme = \"system\",\n enableSystem = true,\n disableTransitionOnChange = false,\n storageKey = \"saas-kit-theme\",\n}: ThemeProviderProps) {\n return (\n <NextThemesProvider\n attribute={attribute}\n defaultTheme={defaultTheme}\n enableSystem={enableSystem}\n disableTransitionOnChange={disableTransitionOnChange}\n storageKey={storageKey}\n >\n {children}\n </NextThemesProvider>\n );\n}\n","\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport { SessionProvider } from \"./session-provider\";\nimport { ThemeProvider } from \"./theme-provider\";\nimport { Toaster } from \"sonner\";\n\nexport interface SaasKitProviderProps {\n children: ReactNode;\n theme?: {\n attribute?: \"class\" | \"data-theme\";\n defaultTheme?: string;\n enableSystem?: boolean;\n disableTransitionOnChange?: boolean;\n storageKey?: string;\n };\n toaster?: {\n position?:\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\"\n | \"top-center\"\n | \"bottom-center\";\n richColors?: boolean;\n closeButton?: boolean;\n };\n}\n\nexport function SaasKitProvider({\n children,\n theme = {},\n toaster = {},\n}: SaasKitProviderProps) {\n return (\n <SessionProvider>\n <ThemeProvider\n attribute={theme.attribute || \"class\"}\n defaultTheme={theme.defaultTheme || \"system\"}\n enableSystem={theme.enableSystem ?? true}\n disableTransitionOnChange={theme.disableTransitionOnChange ?? false}\n storageKey={theme.storageKey || \"saas-kit-theme\"}\n >\n {children}\n <Toaster\n position={toaster.position || \"bottom-right\"}\n richColors={toaster.richColors ?? true}\n closeButton={toaster.closeButton ?? true}\n />\n </ThemeProvider>\n </SessionProvider>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nexport function useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(false);\n\n useEffect(() => {\n const mediaQuery = window.matchMedia(query);\n\n // Set initial value\n setMatches(mediaQuery.matches);\n\n // Create listener\n const handler = (event: MediaQueryListEvent) => {\n setMatches(event.matches);\n };\n\n // Add listener\n mediaQuery.addEventListener(\"change\", handler);\n\n // Cleanup\n return () => {\n mediaQuery.removeEventListener(\"change\", handler);\n };\n }, [query]);\n\n return matches;\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n mql.addEventListener(\"change\", onChange);\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n return () => mql.removeEventListener(\"change\", onChange);\n }, []);\n\n return !!isMobile;\n}\n","\"use client\";\n\nimport { useSession } from \"next-auth/react\";\n\nexport interface CurrentUser {\n id: string;\n name?: string | null;\n email?: string | null;\n image?: string | null;\n role?: string;\n}\n\nexport interface UseCurrentUserReturn {\n user: CurrentUser | null;\n isLoading: boolean;\n isAuthenticated: boolean;\n update: () => Promise<void>;\n}\n\nexport function useCurrentUser(): UseCurrentUserReturn {\n const { data: session, status, update } = useSession();\n\n const isLoading = status === \"loading\";\n const isAuthenticated = status === \"authenticated\";\n\n const user: CurrentUser | null = session?.user\n ? {\n id: session.user.id!,\n name: session.user.name,\n email: session.user.email,\n image: session.user.image,\n role: (session.user as { role?: string }).role,\n }\n : null;\n\n return {\n user,\n isLoading,\n isAuthenticated,\n update: async () => {\n await update();\n },\n };\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { PrismaClient } from \"@prisma/client\";\n\nconst globalForPrisma = globalThis as unknown as {\n prisma: PrismaClient | undefined;\n};\n\nexport const prisma =\n globalForPrisma.prisma ??\n new PrismaClient({\n log:\n process.env.NODE_ENV === \"development\"\n ? [\"query\", \"error\", \"warn\"]\n : [\"error\"],\n });\n\nif (process.env.NODE_ENV !== \"production\") globalForPrisma.prisma = prisma;\n\nexport function createPrismaClient(options?: {\n log?: (\"query\" | \"error\" | \"warn\" | \"info\")[];\n}): PrismaClient {\n return new PrismaClient({\n log: options?.log ?? (process.env.NODE_ENV === \"development\"\n ? [\"query\", \"error\", \"warn\"]\n : [\"error\"]),\n });\n}\n\nexport { PrismaClient };\n"],"mappings":"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","names":["config","jsx","jsx"]}
@@ -0,0 +1,11 @@
1
+ import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
2
+ import * as _prisma_client from '@prisma/client';
3
+ import { PrismaClient } from '@prisma/client';
4
+ export { PrismaClient } from '@prisma/client';
5
+
6
+ declare const prisma: PrismaClient<_prisma_client.Prisma.PrismaClientOptions, never, _prisma_client_runtime_library.DefaultArgs>;
7
+ declare function createPrismaClient(options?: {
8
+ log?: ("query" | "error" | "warn" | "info")[];
9
+ }): PrismaClient;
10
+
11
+ export { createPrismaClient, prisma };
@@ -0,0 +1,11 @@
1
+ import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
2
+ import * as _prisma_client from '@prisma/client';
3
+ import { PrismaClient } from '@prisma/client';
4
+ export { PrismaClient } from '@prisma/client';
5
+
6
+ declare const prisma: PrismaClient<_prisma_client.Prisma.PrismaClientOptions, never, _prisma_client_runtime_library.DefaultArgs>;
7
+ declare function createPrismaClient(options?: {
8
+ log?: ("query" | "error" | "warn" | "info")[];
9
+ }): PrismaClient;
10
+
11
+ export { createPrismaClient, prisma };
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/prisma/index.ts
22
+ var prisma_exports = {};
23
+ __export(prisma_exports, {
24
+ PrismaClient: () => import_client.PrismaClient,
25
+ createPrismaClient: () => createPrismaClient,
26
+ prisma: () => prisma
27
+ });
28
+ module.exports = __toCommonJS(prisma_exports);
29
+ var import_client = require("@prisma/client");
30
+ var globalForPrisma = globalThis;
31
+ var prisma = globalForPrisma.prisma ?? new import_client.PrismaClient({
32
+ log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"]
33
+ });
34
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
35
+ function createPrismaClient(options) {
36
+ return new import_client.PrismaClient({
37
+ log: options?.log ?? (process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"])
38
+ });
39
+ }
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ PrismaClient,
43
+ createPrismaClient,
44
+ prisma
45
+ });
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/prisma/index.ts"],"sourcesContent":["import { PrismaClient } from \"@prisma/client\";\n\nconst globalForPrisma = globalThis as unknown as {\n prisma: PrismaClient | undefined;\n};\n\nexport const prisma =\n globalForPrisma.prisma ??\n new PrismaClient({\n log:\n process.env.NODE_ENV === \"development\"\n ? [\"query\", \"error\", \"warn\"]\n : [\"error\"],\n });\n\nif (process.env.NODE_ENV !== \"production\") globalForPrisma.prisma = prisma;\n\nexport function createPrismaClient(options?: {\n log?: (\"query\" | \"error\" | \"warn\" | \"info\")[];\n}): PrismaClient {\n return new PrismaClient({\n log: options?.log ?? (process.env.NODE_ENV === \"development\"\n ? [\"query\", \"error\", \"warn\"]\n : [\"error\"]),\n });\n}\n\nexport { PrismaClient };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6B;AAE7B,IAAM,kBAAkB;AAIjB,IAAM,SACX,gBAAgB,UAChB,IAAI,2BAAa;AAAA,EACf,KACE,QAAQ,IAAI,aAAa,gBACrB,CAAC,SAAS,SAAS,MAAM,IACzB,CAAC,OAAO;AAChB,CAAC;AAEH,IAAI,QAAQ,IAAI,aAAa,aAAc,iBAAgB,SAAS;AAE7D,SAAS,mBAAmB,SAElB;AACf,SAAO,IAAI,2BAAa;AAAA,IACtB,KAAK,SAAS,QAAQ,QAAQ,IAAI,aAAa,gBAC3C,CAAC,SAAS,SAAS,MAAM,IACzB,CAAC,OAAO;AAAA,EACd,CAAC;AACH;","names":[]}
@@ -0,0 +1,20 @@
1
+ "use client";
2
+
3
+ // src/prisma/index.ts
4
+ import { PrismaClient } from "@prisma/client";
5
+ var globalForPrisma = globalThis;
6
+ var prisma = globalForPrisma.prisma ?? new PrismaClient({
7
+ log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"]
8
+ });
9
+ if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
10
+ function createPrismaClient(options) {
11
+ return new PrismaClient({
12
+ log: options?.log ?? (process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"])
13
+ });
14
+ }
15
+ export {
16
+ PrismaClient,
17
+ createPrismaClient,
18
+ prisma
19
+ };
20
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/prisma/index.ts"],"sourcesContent":["import { PrismaClient } from \"@prisma/client\";\n\nconst globalForPrisma = globalThis as unknown as {\n prisma: PrismaClient | undefined;\n};\n\nexport const prisma =\n globalForPrisma.prisma ??\n new PrismaClient({\n log:\n process.env.NODE_ENV === \"development\"\n ? [\"query\", \"error\", \"warn\"]\n : [\"error\"],\n });\n\nif (process.env.NODE_ENV !== \"production\") globalForPrisma.prisma = prisma;\n\nexport function createPrismaClient(options?: {\n log?: (\"query\" | \"error\" | \"warn\" | \"info\")[];\n}): PrismaClient {\n return new PrismaClient({\n log: options?.log ?? (process.env.NODE_ENV === \"development\"\n ? [\"query\", \"error\", \"warn\"]\n : [\"error\"]),\n });\n}\n\nexport { PrismaClient };\n"],"mappings":";;;AAAA,SAAS,oBAAoB;AAE7B,IAAM,kBAAkB;AAIjB,IAAM,SACX,gBAAgB,UAChB,IAAI,aAAa;AAAA,EACf,KACE,QAAQ,IAAI,aAAa,gBACrB,CAAC,SAAS,SAAS,MAAM,IACzB,CAAC,OAAO;AAChB,CAAC;AAEH,IAAI,QAAQ,IAAI,aAAa,aAAc,iBAAgB,SAAS;AAE7D,SAAS,mBAAmB,SAElB;AACf,SAAO,IAAI,aAAa;AAAA,IACtB,KAAK,SAAS,QAAQ,QAAQ,IAAI,aAAa,gBAC3C,CAAC,SAAS,SAAS,MAAM,IACzB,CAAC,OAAO;AAAA,EACd,CAAC;AACH;","names":[]}
@@ -0,0 +1,37 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { ThemeProviderProps as ThemeProviderProps$1 } from 'next-themes';
4
+
5
+ interface SessionProviderProps {
6
+ children: ReactNode;
7
+ }
8
+ declare function SessionProvider({ children }: SessionProviderProps): react_jsx_runtime.JSX.Element;
9
+
10
+ interface ThemeProviderProps {
11
+ children: ReactNode;
12
+ attribute?: ThemeProviderProps$1["attribute"];
13
+ defaultTheme?: string;
14
+ enableSystem?: boolean;
15
+ disableTransitionOnChange?: boolean;
16
+ storageKey?: string;
17
+ }
18
+ declare function ThemeProvider({ children, attribute, defaultTheme, enableSystem, disableTransitionOnChange, storageKey, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
19
+
20
+ interface SaasKitProviderProps {
21
+ children: ReactNode;
22
+ theme?: {
23
+ attribute?: "class" | "data-theme";
24
+ defaultTheme?: string;
25
+ enableSystem?: boolean;
26
+ disableTransitionOnChange?: boolean;
27
+ storageKey?: string;
28
+ };
29
+ toaster?: {
30
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center";
31
+ richColors?: boolean;
32
+ closeButton?: boolean;
33
+ };
34
+ }
35
+ declare function SaasKitProvider({ children, theme, toaster, }: SaasKitProviderProps): react_jsx_runtime.JSX.Element;
36
+
37
+ export { SaasKitProvider, type SaasKitProviderProps, SessionProvider, type SessionProviderProps, ThemeProvider, type ThemeProviderProps };
@@ -0,0 +1,37 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { ThemeProviderProps as ThemeProviderProps$1 } from 'next-themes';
4
+
5
+ interface SessionProviderProps {
6
+ children: ReactNode;
7
+ }
8
+ declare function SessionProvider({ children }: SessionProviderProps): react_jsx_runtime.JSX.Element;
9
+
10
+ interface ThemeProviderProps {
11
+ children: ReactNode;
12
+ attribute?: ThemeProviderProps$1["attribute"];
13
+ defaultTheme?: string;
14
+ enableSystem?: boolean;
15
+ disableTransitionOnChange?: boolean;
16
+ storageKey?: string;
17
+ }
18
+ declare function ThemeProvider({ children, attribute, defaultTheme, enableSystem, disableTransitionOnChange, storageKey, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
19
+
20
+ interface SaasKitProviderProps {
21
+ children: ReactNode;
22
+ theme?: {
23
+ attribute?: "class" | "data-theme";
24
+ defaultTheme?: string;
25
+ enableSystem?: boolean;
26
+ disableTransitionOnChange?: boolean;
27
+ storageKey?: string;
28
+ };
29
+ toaster?: {
30
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "bottom-center";
31
+ richColors?: boolean;
32
+ closeButton?: boolean;
33
+ };
34
+ }
35
+ declare function SaasKitProvider({ children, theme, toaster, }: SaasKitProviderProps): react_jsx_runtime.JSX.Element;
36
+
37
+ export { SaasKitProvider, type SaasKitProviderProps, SessionProvider, type SessionProviderProps, ThemeProvider, type ThemeProviderProps };