@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.
- package/dist/auth/index.d.mts +40 -0
- package/dist/auth/index.d.ts +40 -0
- package/dist/auth/index.js +147 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +111 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/authorization/index.d.mts +78 -0
- package/dist/authorization/index.d.ts +78 -0
- package/dist/authorization/index.js +137 -0
- package/dist/authorization/index.js.map +1 -0
- package/dist/authorization/index.mjs +104 -0
- package/dist/authorization/index.mjs.map +1 -0
- package/dist/components/auth/index.d.mts +26 -0
- package/dist/components/auth/index.d.ts +26 -0
- package/dist/components/auth/index.js +733 -0
- package/dist/components/auth/index.js.map +1 -0
- package/dist/components/auth/index.mjs +696 -0
- package/dist/components/auth/index.mjs.map +1 -0
- package/dist/components/dashboard/index.d.mts +32 -0
- package/dist/components/dashboard/index.d.ts +32 -0
- package/dist/components/dashboard/index.js +440 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/dashboard/index.mjs +401 -0
- package/dist/components/dashboard/index.mjs.map +1 -0
- package/dist/components/ui/index.d.mts +351 -0
- package/dist/components/ui/index.d.ts +351 -0
- package/dist/components/ui/index.js +14342 -0
- package/dist/components/ui/index.js.map +1 -0
- package/dist/components/ui/index.mjs +14173 -0
- package/dist/components/ui/index.mjs.map +1 -0
- package/dist/config/index.d.mts +45 -0
- package/dist/config/index.d.ts +45 -0
- package/dist/config/index.js +71 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.mjs +44 -0
- package/dist/config/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +20 -0
- package/dist/hooks/index.d.ts +20 -0
- package/dist/hooks/index.js +103 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +65 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +459 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +401 -0
- package/dist/index.mjs.map +1 -0
- package/dist/prisma/index.d.mts +11 -0
- package/dist/prisma/index.d.ts +11 -0
- package/dist/prisma/index.js +46 -0
- package/dist/prisma/index.js.map +1 -0
- package/dist/prisma/index.mjs +20 -0
- package/dist/prisma/index.mjs.map +1 -0
- package/dist/providers/index.d.mts +37 -0
- package/dist/providers/index.d.ts +37 -0
- package/dist/providers/index.js +97 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/index.mjs +69 -0
- package/dist/providers/index.mjs.map +1 -0
- package/dist/sidebar-ttX_iZ40.d.mts +22 -0
- package/dist/sidebar-ttX_iZ40.d.ts +22 -0
- package/package.json +122 -0
- package/prisma/schema.prisma +106 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var src_exports = {};
|
|
33
|
+
__export(src_exports, {
|
|
34
|
+
PERMISSIONS: () => PERMISSIONS,
|
|
35
|
+
PrismaClient: () => import_client.PrismaClient,
|
|
36
|
+
SaasKitProvider: () => SaasKitProvider,
|
|
37
|
+
SessionProvider: () => SessionProvider,
|
|
38
|
+
ThemeProvider: () => ThemeProvider,
|
|
39
|
+
cn: () => cn,
|
|
40
|
+
configureAuthorization: () => configureAuthorization,
|
|
41
|
+
createAuthConfig: () => createAuthConfig,
|
|
42
|
+
createPermissionChecker: () => createPermissionChecker,
|
|
43
|
+
createPrismaClient: () => createPrismaClient,
|
|
44
|
+
createSiteConfig: () => createSiteConfig,
|
|
45
|
+
defineConfig: () => defineConfig,
|
|
46
|
+
hasMinRole: () => hasMinRole,
|
|
47
|
+
hasPermission: () => hasPermission,
|
|
48
|
+
hasRole: () => hasRole,
|
|
49
|
+
isAdmin: () => isAdmin,
|
|
50
|
+
isModerator: () => isModerator,
|
|
51
|
+
isSuperAdmin: () => isSuperAdmin,
|
|
52
|
+
prisma: () => prisma,
|
|
53
|
+
useCurrentUser: () => useCurrentUser,
|
|
54
|
+
useIsMobile: () => useIsMobile,
|
|
55
|
+
useMediaQuery: () => useMediaQuery,
|
|
56
|
+
withRole: () => withRole
|
|
57
|
+
});
|
|
58
|
+
module.exports = __toCommonJS(src_exports);
|
|
59
|
+
|
|
60
|
+
// src/auth/create-auth-config.ts
|
|
61
|
+
var import_google = __toESM(require("next-auth/providers/google"));
|
|
62
|
+
var import_resend = __toESM(require("next-auth/providers/resend"));
|
|
63
|
+
var import_github = __toESM(require("next-auth/providers/github"));
|
|
64
|
+
var import_credentials = __toESM(require("next-auth/providers/credentials"));
|
|
65
|
+
function createProviders(options) {
|
|
66
|
+
const providers = [];
|
|
67
|
+
for (const provider of options.providers) {
|
|
68
|
+
switch (provider) {
|
|
69
|
+
case "google":
|
|
70
|
+
providers.push(
|
|
71
|
+
(0, import_google.default)({
|
|
72
|
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
|
73
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
break;
|
|
77
|
+
case "github":
|
|
78
|
+
providers.push(
|
|
79
|
+
(0, import_github.default)({
|
|
80
|
+
clientId: process.env.GITHUB_CLIENT_ID,
|
|
81
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
break;
|
|
85
|
+
case "email":
|
|
86
|
+
providers.push(
|
|
87
|
+
(0, import_resend.default)({
|
|
88
|
+
apiKey: process.env.AUTH_RESEND_KEY,
|
|
89
|
+
from: options.email?.from || process.env.EMAIL_FROM || "no-reply@example.com"
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
break;
|
|
93
|
+
case "credentials":
|
|
94
|
+
if (options.credentials?.authorize) {
|
|
95
|
+
providers.push(
|
|
96
|
+
(0, import_credentials.default)({
|
|
97
|
+
credentials: {
|
|
98
|
+
email: { label: "Email", type: "email" },
|
|
99
|
+
password: { label: "Password", type: "password" }
|
|
100
|
+
},
|
|
101
|
+
authorize: async (credentials) => {
|
|
102
|
+
if (!credentials?.email || !credentials?.password) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return options.credentials.authorize(credentials);
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return providers;
|
|
114
|
+
}
|
|
115
|
+
function createAuthConfig(options) {
|
|
116
|
+
return {
|
|
117
|
+
adapter: options.adapter,
|
|
118
|
+
session: {
|
|
119
|
+
strategy: options.session?.strategy || "jwt",
|
|
120
|
+
maxAge: options.session?.maxAge || 30 * 24 * 60 * 60
|
|
121
|
+
// 30 days
|
|
122
|
+
},
|
|
123
|
+
providers: createProviders(options),
|
|
124
|
+
pages: {
|
|
125
|
+
signIn: options.pages?.signIn || "/login",
|
|
126
|
+
error: options.pages?.error || "/auth-error",
|
|
127
|
+
verifyRequest: options.pages?.verifyRequest || "/verify-request",
|
|
128
|
+
newUser: options.pages?.newUser
|
|
129
|
+
},
|
|
130
|
+
callbacks: {
|
|
131
|
+
async jwt({ token, user, trigger }) {
|
|
132
|
+
if (user) {
|
|
133
|
+
token.id = user.id;
|
|
134
|
+
if (options.callbacks?.getUserRole) {
|
|
135
|
+
token.role = await options.callbacks.getUserRole(user.id);
|
|
136
|
+
} else {
|
|
137
|
+
token.role = "USER";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (trigger === "update" && token.id && options.callbacks?.getUserRole) {
|
|
141
|
+
token.role = await options.callbacks.getUserRole(token.id);
|
|
142
|
+
}
|
|
143
|
+
return token;
|
|
144
|
+
},
|
|
145
|
+
session({ session, token }) {
|
|
146
|
+
if (session.user && token.id) {
|
|
147
|
+
session.user.id = token.id;
|
|
148
|
+
session.user.role = token.role;
|
|
149
|
+
}
|
|
150
|
+
return session;
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
events: {
|
|
154
|
+
async createUser({ user }) {
|
|
155
|
+
if (options.callbacks?.onUserCreated && user.email) {
|
|
156
|
+
await options.callbacks.onUserCreated({
|
|
157
|
+
id: user.id,
|
|
158
|
+
email: user.email
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/authorization/index.ts
|
|
167
|
+
var import_server = require("next/server");
|
|
168
|
+
var DEFAULT_ROLE_HIERARCHY = ["USER", "MODERATOR", "ADMIN", "SUPER_ADMIN"];
|
|
169
|
+
var config = {
|
|
170
|
+
roleHierarchy: DEFAULT_ROLE_HIERARCHY,
|
|
171
|
+
permissions: {}
|
|
172
|
+
};
|
|
173
|
+
function configureAuthorization(options) {
|
|
174
|
+
config = { ...config, ...options };
|
|
175
|
+
}
|
|
176
|
+
function hasMinRole(userRole, minRole) {
|
|
177
|
+
const hierarchy = config.roleHierarchy || DEFAULT_ROLE_HIERARCHY;
|
|
178
|
+
const userLevel = hierarchy.indexOf(userRole);
|
|
179
|
+
const minLevel = hierarchy.indexOf(minRole);
|
|
180
|
+
if (userLevel === -1 || minLevel === -1) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return userLevel >= minLevel;
|
|
184
|
+
}
|
|
185
|
+
function hasRole(userRole, allowedRoles) {
|
|
186
|
+
return allowedRoles.includes(userRole);
|
|
187
|
+
}
|
|
188
|
+
function isAdmin(role) {
|
|
189
|
+
return hasMinRole(role, "ADMIN");
|
|
190
|
+
}
|
|
191
|
+
function isSuperAdmin(role) {
|
|
192
|
+
return role === "SUPER_ADMIN";
|
|
193
|
+
}
|
|
194
|
+
function isModerator(role) {
|
|
195
|
+
return hasMinRole(role, "MODERATOR");
|
|
196
|
+
}
|
|
197
|
+
function hasPermission(userRole, permission) {
|
|
198
|
+
const permissions = config.permissions || {};
|
|
199
|
+
const allowedRoles = permissions[permission];
|
|
200
|
+
if (!allowedRoles) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return allowedRoles.includes(userRole);
|
|
204
|
+
}
|
|
205
|
+
var PERMISSIONS = {
|
|
206
|
+
// User management
|
|
207
|
+
"users:read": ["MODERATOR", "ADMIN", "SUPER_ADMIN"],
|
|
208
|
+
"users:update": ["ADMIN", "SUPER_ADMIN"],
|
|
209
|
+
"users:delete": ["SUPER_ADMIN"],
|
|
210
|
+
"users:updateRole": ["SUPER_ADMIN"],
|
|
211
|
+
// Content management
|
|
212
|
+
"posts:create": ["MODERATOR", "ADMIN", "SUPER_ADMIN"],
|
|
213
|
+
"posts:update": ["MODERATOR", "ADMIN", "SUPER_ADMIN"],
|
|
214
|
+
"posts:delete": ["ADMIN", "SUPER_ADMIN"],
|
|
215
|
+
"posts:publish": ["ADMIN", "SUPER_ADMIN"],
|
|
216
|
+
// Admin panel access
|
|
217
|
+
"admin:access": ["ADMIN", "SUPER_ADMIN"],
|
|
218
|
+
"admin:settings": ["SUPER_ADMIN"],
|
|
219
|
+
// Subscription management
|
|
220
|
+
"subscriptions:read": ["ADMIN", "SUPER_ADMIN"],
|
|
221
|
+
"subscriptions:manage": ["SUPER_ADMIN"]
|
|
222
|
+
};
|
|
223
|
+
async function withRole(options) {
|
|
224
|
+
const session = await options.getSession();
|
|
225
|
+
if (!session?.user?.id) {
|
|
226
|
+
return {
|
|
227
|
+
authorized: false,
|
|
228
|
+
response: import_server.NextResponse.json({ error: "Unauthorized" }, { status: 401 }),
|
|
229
|
+
session: null
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const userRole = session.user.role || "USER";
|
|
233
|
+
if (!hasMinRole(userRole, options.minRole)) {
|
|
234
|
+
return {
|
|
235
|
+
authorized: false,
|
|
236
|
+
response: import_server.NextResponse.json({ error: "Forbidden" }, { status: 403 }),
|
|
237
|
+
session
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
authorized: true,
|
|
242
|
+
response: null,
|
|
243
|
+
session
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function createPermissionChecker(permissions) {
|
|
247
|
+
return function checkPermission(userRole, permission) {
|
|
248
|
+
const allowedRoles = permissions[permission];
|
|
249
|
+
if (!allowedRoles) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
return allowedRoles.includes(userRole);
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/config/define-config.ts
|
|
257
|
+
function defineConfig(config2) {
|
|
258
|
+
return {
|
|
259
|
+
app: {
|
|
260
|
+
name: config2.app.name,
|
|
261
|
+
url: config2.app.url || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000",
|
|
262
|
+
description: config2.app.description || ""
|
|
263
|
+
},
|
|
264
|
+
auth: {
|
|
265
|
+
providers: config2.auth.providers,
|
|
266
|
+
pages: {
|
|
267
|
+
signIn: config2.auth.pages?.signIn || "/login",
|
|
268
|
+
error: config2.auth.pages?.error || "/auth-error",
|
|
269
|
+
verifyRequest: config2.auth.pages?.verifyRequest || "/verify-request",
|
|
270
|
+
...config2.auth.pages
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
dashboard: config2.dashboard,
|
|
274
|
+
features: {
|
|
275
|
+
payments: config2.features?.payments ?? false,
|
|
276
|
+
admin: config2.features?.admin ?? false,
|
|
277
|
+
blog: config2.features?.blog ?? false
|
|
278
|
+
},
|
|
279
|
+
theme: {
|
|
280
|
+
defaultTheme: config2.theme?.defaultTheme || "system",
|
|
281
|
+
enableSystem: config2.theme?.enableSystem ?? true,
|
|
282
|
+
storageKey: config2.theme?.storageKey || "saas-kit-theme"
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function createSiteConfig(config2) {
|
|
287
|
+
return {
|
|
288
|
+
name: config2.app.name,
|
|
289
|
+
description: config2.app.description || "",
|
|
290
|
+
url: config2.app.url || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// src/providers/session-provider.tsx
|
|
295
|
+
var import_react = require("next-auth/react");
|
|
296
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
297
|
+
function SessionProvider({ children }) {
|
|
298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.SessionProvider, { children });
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/providers/theme-provider.tsx
|
|
302
|
+
var import_next_themes = require("next-themes");
|
|
303
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
304
|
+
function ThemeProvider({
|
|
305
|
+
children,
|
|
306
|
+
attribute = "class",
|
|
307
|
+
defaultTheme = "system",
|
|
308
|
+
enableSystem = true,
|
|
309
|
+
disableTransitionOnChange = false,
|
|
310
|
+
storageKey = "saas-kit-theme"
|
|
311
|
+
}) {
|
|
312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
313
|
+
import_next_themes.ThemeProvider,
|
|
314
|
+
{
|
|
315
|
+
attribute,
|
|
316
|
+
defaultTheme,
|
|
317
|
+
enableSystem,
|
|
318
|
+
disableTransitionOnChange,
|
|
319
|
+
storageKey,
|
|
320
|
+
children
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/providers/saas-kit-provider.tsx
|
|
326
|
+
var import_sonner = require("sonner");
|
|
327
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
328
|
+
function SaasKitProvider({
|
|
329
|
+
children,
|
|
330
|
+
theme = {},
|
|
331
|
+
toaster = {}
|
|
332
|
+
}) {
|
|
333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SessionProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
334
|
+
ThemeProvider,
|
|
335
|
+
{
|
|
336
|
+
attribute: theme.attribute || "class",
|
|
337
|
+
defaultTheme: theme.defaultTheme || "system",
|
|
338
|
+
enableSystem: theme.enableSystem ?? true,
|
|
339
|
+
disableTransitionOnChange: theme.disableTransitionOnChange ?? false,
|
|
340
|
+
storageKey: theme.storageKey || "saas-kit-theme",
|
|
341
|
+
children: [
|
|
342
|
+
children,
|
|
343
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
344
|
+
import_sonner.Toaster,
|
|
345
|
+
{
|
|
346
|
+
position: toaster.position || "bottom-right",
|
|
347
|
+
richColors: toaster.richColors ?? true,
|
|
348
|
+
closeButton: toaster.closeButton ?? true
|
|
349
|
+
}
|
|
350
|
+
)
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
) });
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/hooks/use-media-query.ts
|
|
357
|
+
var import_react2 = require("react");
|
|
358
|
+
function useMediaQuery(query) {
|
|
359
|
+
const [matches, setMatches] = (0, import_react2.useState)(false);
|
|
360
|
+
(0, import_react2.useEffect)(() => {
|
|
361
|
+
const mediaQuery = window.matchMedia(query);
|
|
362
|
+
setMatches(mediaQuery.matches);
|
|
363
|
+
const handler = (event) => {
|
|
364
|
+
setMatches(event.matches);
|
|
365
|
+
};
|
|
366
|
+
mediaQuery.addEventListener("change", handler);
|
|
367
|
+
return () => {
|
|
368
|
+
mediaQuery.removeEventListener("change", handler);
|
|
369
|
+
};
|
|
370
|
+
}, [query]);
|
|
371
|
+
return matches;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// src/hooks/use-mobile.ts
|
|
375
|
+
var React = __toESM(require("react"));
|
|
376
|
+
var MOBILE_BREAKPOINT = 768;
|
|
377
|
+
function useIsMobile() {
|
|
378
|
+
const [isMobile, setIsMobile] = React.useState(void 0);
|
|
379
|
+
React.useEffect(() => {
|
|
380
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
381
|
+
const onChange = () => {
|
|
382
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
383
|
+
};
|
|
384
|
+
mql.addEventListener("change", onChange);
|
|
385
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
386
|
+
return () => mql.removeEventListener("change", onChange);
|
|
387
|
+
}, []);
|
|
388
|
+
return !!isMobile;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/hooks/use-current-user.ts
|
|
392
|
+
var import_react3 = require("next-auth/react");
|
|
393
|
+
function useCurrentUser() {
|
|
394
|
+
const { data: session, status, update } = (0, import_react3.useSession)();
|
|
395
|
+
const isLoading = status === "loading";
|
|
396
|
+
const isAuthenticated = status === "authenticated";
|
|
397
|
+
const user = session?.user ? {
|
|
398
|
+
id: session.user.id,
|
|
399
|
+
name: session.user.name,
|
|
400
|
+
email: session.user.email,
|
|
401
|
+
image: session.user.image,
|
|
402
|
+
role: session.user.role
|
|
403
|
+
} : null;
|
|
404
|
+
return {
|
|
405
|
+
user,
|
|
406
|
+
isLoading,
|
|
407
|
+
isAuthenticated,
|
|
408
|
+
update: async () => {
|
|
409
|
+
await update();
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// src/lib/utils.ts
|
|
415
|
+
var import_clsx = require("clsx");
|
|
416
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
417
|
+
function cn(...inputs) {
|
|
418
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// src/prisma/index.ts
|
|
422
|
+
var import_client = require("@prisma/client");
|
|
423
|
+
var globalForPrisma = globalThis;
|
|
424
|
+
var prisma = globalForPrisma.prisma ?? new import_client.PrismaClient({
|
|
425
|
+
log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"]
|
|
426
|
+
});
|
|
427
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
428
|
+
function createPrismaClient(options) {
|
|
429
|
+
return new import_client.PrismaClient({
|
|
430
|
+
log: options?.log ?? (process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"])
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
434
|
+
0 && (module.exports = {
|
|
435
|
+
PERMISSIONS,
|
|
436
|
+
PrismaClient,
|
|
437
|
+
SaasKitProvider,
|
|
438
|
+
SessionProvider,
|
|
439
|
+
ThemeProvider,
|
|
440
|
+
cn,
|
|
441
|
+
configureAuthorization,
|
|
442
|
+
createAuthConfig,
|
|
443
|
+
createPermissionChecker,
|
|
444
|
+
createPrismaClient,
|
|
445
|
+
createSiteConfig,
|
|
446
|
+
defineConfig,
|
|
447
|
+
hasMinRole,
|
|
448
|
+
hasPermission,
|
|
449
|
+
hasRole,
|
|
450
|
+
isAdmin,
|
|
451
|
+
isModerator,
|
|
452
|
+
isSuperAdmin,
|
|
453
|
+
prisma,
|
|
454
|
+
useCurrentUser,
|
|
455
|
+
useIsMobile,
|
|
456
|
+
useMediaQuery,
|
|
457
|
+
withRole
|
|
458
|
+
});
|
|
459
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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":["// Auth\nexport { createAuthConfig } from \"./auth/create-auth-config\";\nexport type { AuthConfigOptions, AuthProvider } from \"./auth/create-auth-config\";\n\n// Authorization\nexport {\n hasMinRole,\n hasRole,\n isAdmin,\n isSuperAdmin,\n isModerator,\n hasPermission,\n withRole,\n configureAuthorization,\n createPermissionChecker,\n PERMISSIONS,\n} from \"./authorization\";\nexport type { Role, Permission, WithRoleResult, WithRoleOptions } from \"./authorization\";\n\n// Config\nexport { defineConfig, createSiteConfig } from \"./config/define-config\";\nexport type { SaasKitConfig } from \"./config/define-config\";\n\n// Providers\nexport { SessionProvider, ThemeProvider, SaasKitProvider } from \"./providers\";\nexport type { SessionProviderProps, ThemeProviderProps, SaasKitProviderProps } from \"./providers\";\n\n// Hooks\nexport { useMediaQuery, useIsMobile, useCurrentUser } from \"./hooks\";\nexport type { CurrentUser, UseCurrentUserReturn } from \"./hooks\";\n\n// Utils\nexport { cn } from \"./lib/utils\";\n\n// Re-export prisma\nexport { prisma, createPrismaClient, PrismaClient } from \"./prisma\";\n","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":["Google","GitHub","Resend","Credentials","config","NextAuthSessionProvider","import_jsx_runtime","NextThemesProvider","import_jsx_runtime","import_react","import_react"]}
|