hylekit 1.0.2 → 1.0.4

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 (54) hide show
  1. package/README.md +126 -59
  2. package/dist/bff/index.cjs +5 -139
  3. package/dist/bff/index.cjs.map +1 -1
  4. package/dist/bff/index.d.cts +2 -1
  5. package/dist/bff/index.d.ts +2 -1
  6. package/dist/bff/index.js +5 -145
  7. package/dist/bff/index.js.map +1 -1
  8. package/dist/client/index.cjs +58 -0
  9. package/dist/client/index.cjs.map +1 -0
  10. package/dist/client/index.d.cts +1530 -0
  11. package/dist/client/index.d.ts +1530 -0
  12. package/dist/client/index.js +31 -0
  13. package/dist/client/index.js.map +1 -0
  14. package/dist/client/nextjs.cjs +3 -214
  15. package/dist/client/nextjs.cjs.map +1 -1
  16. package/dist/client/nextjs.d.cts +4 -97
  17. package/dist/client/nextjs.d.ts +4 -97
  18. package/dist/client/nextjs.js +2 -218
  19. package/dist/client/nextjs.js.map +1 -1
  20. package/dist/client/sveltekit.cjs +3 -201
  21. package/dist/client/sveltekit.cjs.map +1 -1
  22. package/dist/client/sveltekit.d.cts +3 -72
  23. package/dist/client/sveltekit.d.ts +3 -72
  24. package/dist/client/sveltekit.js +2 -205
  25. package/dist/client/sveltekit.js.map +1 -1
  26. package/dist/{index-DYW73KK3.d.cts → index-B-5TEr94.d.cts} +28 -2
  27. package/dist/{index-DYW73KK3.d.ts → index-B-5TEr94.d.ts} +28 -2
  28. package/dist/index.cjs +276 -262
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +110 -3272
  31. package/dist/index.d.ts +110 -3272
  32. package/dist/index.js +270 -258
  33. package/dist/index.js.map +1 -1
  34. package/dist/server/express.cjs +71 -80
  35. package/dist/server/express.cjs.map +1 -1
  36. package/dist/server/express.d.cts +18 -6
  37. package/dist/server/express.d.ts +18 -6
  38. package/dist/server/express.js +70 -86
  39. package/dist/server/express.js.map +1 -1
  40. package/dist/server/nextjs.cjs +107 -0
  41. package/dist/server/nextjs.cjs.map +1 -0
  42. package/dist/server/nextjs.d.cts +90 -0
  43. package/dist/server/nextjs.d.ts +90 -0
  44. package/dist/server/nextjs.js +82 -0
  45. package/dist/server/nextjs.js.map +1 -0
  46. package/dist/server/sveltekit.cjs +94 -0
  47. package/dist/server/sveltekit.cjs.map +1 -0
  48. package/dist/server/sveltekit.d.cts +68 -0
  49. package/dist/server/sveltekit.d.ts +68 -0
  50. package/dist/server/sveltekit.js +69 -0
  51. package/dist/server/sveltekit.js.map +1 -0
  52. package/dist/{types-GOn9sn7-.d.ts → types-Wucl0qmN.d.cts} +1 -8
  53. package/dist/{types-BHiK1JUX.d.cts → types-Wucl0qmN.d.ts} +1 -8
  54. package/package.json +24 -7
@@ -1,24 +1,4 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/lib/db.ts
8
- import { drizzle } from "drizzle-orm/libsql";
9
- import { createClient } from "@libsql/client";
10
-
11
1
  // src/lib/schema.ts
12
- var schema_exports = {};
13
- __export(schema_exports, {
14
- account: () => account,
15
- accountRelations: () => accountRelations,
16
- session: () => session,
17
- sessionRelations: () => sessionRelations,
18
- user: () => user,
19
- userRelations: () => userRelations,
20
- verification: () => verification
21
- });
22
2
  import { relations, sql } from "drizzle-orm";
23
3
  import { sqliteTable, text, integer, index } from "drizzle-orm/sqlite-core";
24
4
  var user = sqliteTable("user", {
@@ -96,13 +76,6 @@ var accountRelations = relations(account, ({ one }) => ({
96
76
  })
97
77
  }));
98
78
 
99
- // src/lib/db.ts
100
- var client = createClient({
101
- url: process.env.DATABASE_URL,
102
- authToken: process.env.DATABASE_AUTH_TOKEN
103
- });
104
- var db = drizzle(client, { schema: schema_exports });
105
-
106
79
  // src/server/express.ts
107
80
  import { eq, and, gt } from "drizzle-orm";
108
81
  function isUnauthenticatedRoute(path, patterns) {
@@ -123,76 +96,84 @@ function isUnauthenticatedRoute(path, patterns) {
123
96
  }
124
97
  return false;
125
98
  }
126
- var middleware = (options = {}) => {
127
- const {
128
- unauthenticatedRoutes = [],
129
- verifySession = false,
130
- required = true
131
- } = options;
132
- return async (req, res, next) => {
133
- const authReq = req;
134
- if (isUnauthenticatedRoute(req.path, unauthenticatedRoutes)) {
135
- return next();
99
+ var createExpressMiddleware = (db) => {
100
+ return (options = {}) => {
101
+ const {
102
+ unauthenticatedRoutes = [],
103
+ verifySession = false,
104
+ required = true
105
+ } = options;
106
+ if (verifySession && !db) {
107
+ throw new Error(
108
+ "[hylekit] CONFIGURATION ERROR: verifySession requires a database instance. Pass a db instance to createExpressMiddleware(db)."
109
+ );
136
110
  }
137
- try {
138
- const userHeader = req.headers["x-hyle-user"];
139
- const sessionHeader = req.headers["x-hyle-session"];
140
- if (!sessionHeader || typeof sessionHeader !== "string") {
141
- if (required) {
142
- return res.status(401).json({ error: "Unauthorized" });
143
- }
111
+ return async (req, res, next) => {
112
+ const authReq = req;
113
+ if (isUnauthenticatedRoute(req.path, unauthenticatedRoutes)) {
144
114
  return next();
145
115
  }
146
- const sessionData = JSON.parse(
147
- Buffer.from(sessionHeader, "base64").toString("utf-8")
148
- );
149
- if (verifySession) {
150
- const result = await db.select({
151
- session,
152
- user
153
- }).from(session).innerJoin(user, eq(session.userId, user.id)).where(
154
- and(
155
- eq(session.id, sessionData.id),
156
- gt(session.expiresAt, /* @__PURE__ */ new Date())
157
- )
158
- ).limit(1);
159
- if (result.length === 0) {
116
+ try {
117
+ const userHeader = req.headers["x-hyle-user"];
118
+ const sessionHeader = req.headers["x-hyle-session"];
119
+ if (!sessionHeader || typeof sessionHeader !== "string") {
160
120
  if (required) {
161
- return res.status(401).json({ error: "Invalid or expired session" });
121
+ return res.status(401).json({ error: "Unauthorized" });
162
122
  }
163
123
  return next();
164
124
  }
165
- authReq.authUser = result[0].user;
166
- authReq.authSession = result[0].session;
167
- authReq.user = authReq.authUser;
168
- authReq.session = authReq.authSession;
169
- return next();
170
- }
171
- let userData;
172
- if (userHeader && typeof userHeader === "string") {
173
- userData = JSON.parse(
174
- Buffer.from(userHeader, "base64").toString("utf-8")
125
+ const sessionData = JSON.parse(
126
+ Buffer.from(sessionHeader, "base64").toString("utf-8")
175
127
  );
128
+ if (verifySession && db) {
129
+ const result = await db.select({
130
+ session,
131
+ user
132
+ }).from(session).innerJoin(user, eq(session.userId, user.id)).where(
133
+ and(
134
+ eq(session.id, sessionData.id),
135
+ gt(session.expiresAt, /* @__PURE__ */ new Date())
136
+ )
137
+ ).limit(1);
138
+ if (result.length === 0) {
139
+ if (required) {
140
+ return res.status(401).json({ error: "Invalid or expired session" });
141
+ }
142
+ return next();
143
+ }
144
+ authReq.authUser = result[0].user;
145
+ authReq.authSession = result[0].session;
146
+ authReq.user = authReq.authUser;
147
+ authReq.session = authReq.authSession;
148
+ return next();
149
+ }
150
+ let userData;
151
+ if (userHeader && typeof userHeader === "string") {
152
+ userData = JSON.parse(
153
+ Buffer.from(userHeader, "base64").toString("utf-8")
154
+ );
155
+ }
156
+ if (!userData && required) {
157
+ return res.status(401).json({ error: "Unauthorized" });
158
+ }
159
+ if (userData) {
160
+ authReq.authUser = userData;
161
+ authReq.authSession = sessionData;
162
+ authReq.user = authReq.authUser;
163
+ authReq.session = authReq.authSession;
164
+ }
165
+ next();
166
+ } catch (error) {
167
+ console.error("[hyle] Auth middleware error:", error);
168
+ if (required) {
169
+ return res.status(401).json({ error: "Authentication failed" });
170
+ }
171
+ next();
176
172
  }
177
- if (!userData && required) {
178
- return res.status(401).json({ error: "Unauthorized" });
179
- }
180
- if (userData) {
181
- authReq.authUser = userData;
182
- authReq.authSession = sessionData;
183
- authReq.user = authReq.authUser;
184
- authReq.session = authReq.authSession;
185
- }
186
- next();
187
- } catch (error) {
188
- console.error("[hyle] Auth middleware error:", error);
189
- if (required) {
190
- return res.status(401).json({ error: "Authentication failed" });
191
- }
192
- next();
193
- }
173
+ };
194
174
  };
195
175
  };
176
+ var middleware = createExpressMiddleware();
196
177
  function isAuthenticated(req) {
197
178
  return !!req.authUser;
198
179
  }
@@ -204,12 +185,15 @@ function getAuthContext(req) {
204
185
  return { user: authReq.authUser, session: authReq.authSession };
205
186
  }
206
187
  var expressAdapter = {
188
+ createMiddleware: createExpressMiddleware,
189
+ /** @deprecated Use createMiddleware instead */
207
190
  middleware,
208
191
  isAuthenticated,
209
192
  getAuthContext
210
193
  };
211
194
  var express_default = expressAdapter;
212
195
  export {
196
+ createExpressMiddleware,
213
197
  express_default as default,
214
198
  expressAdapter,
215
199
  getAuthContext,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/db.ts","../../src/lib/schema.ts","../../src/server/express.ts"],"sourcesContent":["import { drizzle } from \"drizzle-orm/libsql\";\nimport { createClient } from \"@libsql/client\";\nimport * as schema from \"./schema\";\n\nconst client = createClient({\n url: process.env.DATABASE_URL!,\n authToken: process.env.DATABASE_AUTH_TOKEN!,\n});\n\nexport const db = drizzle(client, { schema });\n","import { relations, sql } from \"drizzle-orm\";\nimport { sqliteTable, text, integer, index } from \"drizzle-orm/sqlite-core\";\n\nexport const user = sqliteTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n email: text(\"email\").notNull().unique(),\n emailVerified: integer(\"email_verified\", { mode: \"boolean\" })\n .default(false)\n .notNull(),\n image: text(\"image\"),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const session = sqliteTable(\n \"session\",\n {\n id: text(\"id\").primaryKey(),\n expiresAt: integer(\"expires_at\", { mode: \"timestamp_ms\" }).notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n },\n (table) => [index(\"session_userId_idx\").on(table.userId)],\n);\n\nexport const account = sqliteTable(\n \"account\",\n {\n id: text(\"id\").primaryKey(),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: integer(\"access_token_expires_at\", {\n mode: \"timestamp_ms\",\n }),\n refreshTokenExpiresAt: integer(\"refresh_token_expires_at\", {\n mode: \"timestamp_ms\",\n }),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"account_userId_idx\").on(table.userId)],\n);\n\nexport const verification = sqliteTable(\n \"verification\",\n {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: integer(\"expires_at\", { mode: \"timestamp_ms\" }).notNull(),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"verification_identifier_idx\").on(table.identifier)],\n);\n\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n}));\n\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n","import type { Request, Response, NextFunction } from \"express\";\nimport type { Session, User } from \"better-auth\";\nimport { db } from \"../lib/db\";\nimport { session as sessionTable, user as userTable } from \"../lib/schema\";\nimport { eq, and, gt } from \"drizzle-orm\";\n\n/**\n * Extended Request with authenticated user context.\n */\nexport interface AuthenticatedRequest extends Request {\n /**\n * The authenticated user. Available on all authenticated routes.\n */\n authUser: User;\n\n /**\n * The current session. Available on all authenticated routes.\n */\n authSession: Session;\n\n /**\n * @deprecated Use authUser instead\n */\n user?: User;\n\n /**\n * @deprecated Use authSession instead\n */\n session?: Session;\n}\n\nexport interface MiddlewareOptions {\n /**\n * Routes that don't require authentication.\n * Supports exact paths and patterns with wildcards.\n * @example [\"/health\", \"/public/*\", \"/api/webhooks/*\"]\n */\n unauthenticatedRoutes?: string[];\n\n /**\n * If true, verify session against the database.\n * Use for service-to-service calls where headers can't be implicitly trusted.\n * @default false\n */\n verifySession?: boolean;\n\n /**\n * Whether to require authentication for non-unauthenticated routes.\n * Returns 401 on missing/invalid session.\n * @default true\n */\n required?: boolean;\n}\n\n/**\n * Check if a path matches any of the unauthenticated route patterns.\n */\nfunction isUnauthenticatedRoute(path: string, patterns: string[]): boolean {\n for (const pattern of patterns) {\n if (pattern === path) return true;\n\n // Handle wildcard patterns like \"/public/*\"\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n return true;\n }\n }\n\n // Handle double wildcard patterns like \"/api/**/health\"\n if (pattern.includes(\"**\")) {\n const regex = new RegExp(\n \"^\" + pattern.replace(/\\*\\*/g, \".*\").replace(/\\*/g, \"[^/]*\") + \"$\"\n );\n if (regex.test(path)) return true;\n }\n }\n return false;\n}\n\n/**\n * Express middleware for session verification.\n * \n * @example\n * // Basic usage - trust headers from BFF\n * app.use(middleware());\n * \n * @example\n * // With DB verification for service-to-service calls\n * app.use(middleware({ verifySession: true }));\n * \n * @example\n * // With unauthenticated routes\n * app.use(middleware({\n * unauthenticatedRoutes: [\"/health\", \"/public/*\", \"/api/webhooks/*\"],\n * verifySession: true\n * }));\n */\nexport const middleware = (options: MiddlewareOptions = {}) => {\n const {\n unauthenticatedRoutes = [],\n verifySession = false,\n required = true\n } = options;\n\n return async (req: Request, res: Response, next: NextFunction) => {\n const authReq = req as AuthenticatedRequest;\n\n // Check if route is unauthenticated\n if (isUnauthenticatedRoute(req.path, unauthenticatedRoutes)) {\n return next();\n }\n\n try {\n const userHeader = req.headers[\"x-hyle-user\"];\n const sessionHeader = req.headers[\"x-hyle-session\"];\n\n // No session header provided\n if (!sessionHeader || typeof sessionHeader !== \"string\") {\n if (required) {\n return res.status(401).json({ error: \"Unauthorized\" });\n }\n return next();\n }\n\n const sessionData = JSON.parse(\n Buffer.from(sessionHeader, \"base64\").toString(\"utf-8\")\n );\n\n // Verify session against DB if required\n if (verifySession) {\n const result = await db\n .select({\n session: sessionTable,\n user: userTable,\n })\n .from(sessionTable)\n .innerJoin(userTable, eq(sessionTable.userId, userTable.id))\n .where(\n and(\n eq(sessionTable.id, sessionData.id),\n gt(sessionTable.expiresAt, new Date())\n )\n )\n .limit(1);\n\n if (result.length === 0) {\n if (required) {\n return res.status(401).json({ error: \"Invalid or expired session\" });\n }\n return next();\n }\n\n // Inject auth context\n authReq.authUser = result[0].user as User;\n authReq.authSession = result[0].session as Session;\n\n // Keep deprecated properties for backwards compatibility\n authReq.user = authReq.authUser;\n authReq.session = authReq.authSession;\n\n return next();\n }\n\n // Trust headers mode (for internal BFF calls)\n let userData: User | undefined;\n\n if (userHeader && typeof userHeader === \"string\") {\n userData = JSON.parse(\n Buffer.from(userHeader, \"base64\").toString(\"utf-8\")\n );\n }\n\n if (!userData && required) {\n return res.status(401).json({ error: \"Unauthorized\" });\n }\n\n if (userData) {\n // Inject auth context\n authReq.authUser = userData;\n authReq.authSession = sessionData as Session;\n\n // Keep deprecated properties for backwards compatibility\n authReq.user = authReq.authUser;\n authReq.session = authReq.authSession;\n }\n\n next();\n } catch (error) {\n console.error(\"[hyle] Auth middleware error:\", error);\n if (required) {\n return res.status(401).json({ error: \"Authentication failed\" });\n }\n next();\n }\n };\n};\n\n/**\n * Type guard to check if request is authenticated.\n */\nexport function isAuthenticated(req: Request): req is AuthenticatedRequest {\n return !!(req as AuthenticatedRequest).authUser;\n}\n\n/**\n * Helper to get auth context from request.\n * Throws if not authenticated.\n */\nexport function getAuthContext(req: Request): { user: User; session: Session } {\n const authReq = req as AuthenticatedRequest;\n if (!authReq.authUser || !authReq.authSession) {\n throw new Error(\"Request is not authenticated\");\n }\n return { user: authReq.authUser, session: authReq.authSession };\n}\n\n/**\n * Express adapter exports\n */\nexport const expressAdapter = {\n middleware,\n isAuthenticated,\n getAuthContext,\n};\n\n// Default export for convenience\nexport default expressAdapter;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/lib/schema.ts","../../src/server/express.ts"],"sourcesContent":["import { relations, sql } from \"drizzle-orm\";\nimport { sqliteTable, text, integer, index } from \"drizzle-orm/sqlite-core\";\n\nexport const user = sqliteTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n email: text(\"email\").notNull().unique(),\n emailVerified: integer(\"email_verified\", { mode: \"boolean\" })\n .default(false)\n .notNull(),\n image: text(\"image\"),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const session = sqliteTable(\n \"session\",\n {\n id: text(\"id\").primaryKey(),\n expiresAt: integer(\"expires_at\", { mode: \"timestamp_ms\" }).notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n },\n (table) => [index(\"session_userId_idx\").on(table.userId)],\n);\n\nexport const account = sqliteTable(\n \"account\",\n {\n id: text(\"id\").primaryKey(),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: integer(\"access_token_expires_at\", {\n mode: \"timestamp_ms\",\n }),\n refreshTokenExpiresAt: integer(\"refresh_token_expires_at\", {\n mode: \"timestamp_ms\",\n }),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"account_userId_idx\").on(table.userId)],\n);\n\nexport const verification = sqliteTable(\n \"verification\",\n {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: integer(\"expires_at\", { mode: \"timestamp_ms\" }).notNull(),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .default(sql`(cast(unixepoch('subsecond') * 1000 as integer))`)\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"verification_identifier_idx\").on(table.identifier)],\n);\n\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n}));\n\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n","import type { Request, Response, NextFunction } from \"express\";\nimport type { Session, User } from \"better-auth\";\nimport { session as sessionTable, user as userTable } from \"../lib/schema\";\nimport { eq, and, gt } from \"drizzle-orm\";\n\n/**\n * Extended Request with authenticated user context.\n */\nexport interface AuthenticatedRequest extends Request {\n /**\n * The authenticated user. Available on all authenticated routes.\n */\n authUser: User;\n\n /**\n * The current session. Available on all authenticated routes.\n */\n authSession: Session;\n\n /**\n * @deprecated Use authUser instead\n */\n user?: User;\n\n /**\n * @deprecated Use authSession instead\n */\n session?: Session;\n}\n\nexport interface MiddlewareOptions {\n /**\n * Routes that don't require authentication.\n * Supports exact paths and patterns with wildcards.\n * @example [\"/health\", \"/public/*\", \"/api/webhooks/*\"]\n */\n unauthenticatedRoutes?: string[];\n\n /**\n * If true, verify session against the database.\n * Use for service-to-service calls where headers can't be implicitly trusted.\n * @default false\n */\n verifySession?: boolean;\n\n /**\n * Whether to require authentication for non-unauthenticated routes.\n * Returns 401 on missing/invalid session.\n * @default true\n */\n required?: boolean;\n}\n\n// Type for db instance created by createDb \ntype HyleDb = ReturnType<typeof import(\"drizzle-orm/libsql\").drizzle>;\n\n/**\n * Check if a path matches any of the unauthenticated route patterns.\n */\nfunction isUnauthenticatedRoute(path: string, patterns: string[]): boolean {\n for (const pattern of patterns) {\n if (pattern === path) return true;\n\n // Handle wildcard patterns like \"/public/*\"\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -2);\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n return true;\n }\n }\n\n // Handle double wildcard patterns like \"/api/**/health\"\n if (pattern.includes(\"**\")) {\n const regex = new RegExp(\n \"^\" + pattern.replace(/\\*\\*/g, \".*\").replace(/\\*/g, \"[^/]*\") + \"$\"\n );\n if (regex.test(path)) return true;\n }\n }\n return false;\n}\n\n/**\n * Creates Express middleware for session verification.\n * \n * @param db - Database instance created by createDb() (optional, required if using verifySession)\n * \n * @example\n * // Basic usage - trust headers from BFF (no db needed)\n * app.use(createExpressMiddleware()());\n * \n * @example\n * // With DB verification for service-to-service calls\n * import { createDb } from \"hylekit\";\n * const db = createDb({ url: process.env.HYLE_DATABASE_URL!, authToken: process.env.HYLE_DATABASE_AUTH_TOKEN });\n * app.use(createExpressMiddleware(db)({ verifySession: true }));\n * \n * @example\n * // With unauthenticated routes\n * app.use(createExpressMiddleware(db)({\n * unauthenticatedRoutes: [\"/health\", \"/public/*\", \"/api/webhooks/*\"],\n * verifySession: true\n * }));\n */\nexport const createExpressMiddleware = (db?: HyleDb) => {\n return (options: MiddlewareOptions = {}) => {\n const {\n unauthenticatedRoutes = [],\n verifySession = false,\n required = true\n } = options;\n\n if (verifySession && !db) {\n throw new Error(\n \"[hylekit] CONFIGURATION ERROR: verifySession requires a database instance. \" +\n \"Pass a db instance to createExpressMiddleware(db).\"\n );\n }\n\n return async (req: Request, res: Response, next: NextFunction) => {\n const authReq = req as AuthenticatedRequest;\n\n // Check if route is unauthenticated\n if (isUnauthenticatedRoute(req.path, unauthenticatedRoutes)) {\n return next();\n }\n\n try {\n const userHeader = req.headers[\"x-hyle-user\"];\n const sessionHeader = req.headers[\"x-hyle-session\"];\n\n // No session header provided\n if (!sessionHeader || typeof sessionHeader !== \"string\") {\n if (required) {\n return res.status(401).json({ error: \"Unauthorized\" });\n }\n return next();\n }\n\n const sessionData = JSON.parse(\n Buffer.from(sessionHeader, \"base64\").toString(\"utf-8\")\n );\n\n // Verify session against DB if required\n if (verifySession && db) {\n const result = await db\n .select({\n session: sessionTable,\n user: userTable,\n })\n .from(sessionTable)\n .innerJoin(userTable, eq(sessionTable.userId, userTable.id))\n .where(\n and(\n eq(sessionTable.id, sessionData.id),\n gt(sessionTable.expiresAt, new Date())\n )\n )\n .limit(1);\n\n if (result.length === 0) {\n if (required) {\n return res.status(401).json({ error: \"Invalid or expired session\" });\n }\n return next();\n }\n\n // Inject auth context\n authReq.authUser = result[0].user as User;\n authReq.authSession = result[0].session as Session;\n\n // Keep deprecated properties for backwards compatibility\n authReq.user = authReq.authUser;\n authReq.session = authReq.authSession;\n\n return next();\n }\n\n // Trust headers mode (for internal BFF calls)\n let userData: User | undefined;\n\n if (userHeader && typeof userHeader === \"string\") {\n userData = JSON.parse(\n Buffer.from(userHeader, \"base64\").toString(\"utf-8\")\n );\n }\n\n if (!userData && required) {\n return res.status(401).json({ error: \"Unauthorized\" });\n }\n\n if (userData) {\n // Inject auth context\n authReq.authUser = userData;\n authReq.authSession = sessionData as Session;\n\n // Keep deprecated properties for backwards compatibility\n authReq.user = authReq.authUser;\n authReq.session = authReq.authSession;\n }\n\n next();\n } catch (error) {\n console.error(\"[hyle] Auth middleware error:\", error);\n if (required) {\n return res.status(401).json({ error: \"Authentication failed\" });\n }\n next();\n }\n };\n };\n};\n\n/**\n * @deprecated Use createExpressMiddleware(db) instead. This export will be removed in a future version.\n */\nexport const middleware = createExpressMiddleware();\n\n/**\n * Type guard to check if request is authenticated.\n */\nexport function isAuthenticated(req: Request): req is AuthenticatedRequest {\n return !!(req as AuthenticatedRequest).authUser;\n}\n\n/**\n * Helper to get auth context from request.\n * Throws if not authenticated.\n */\nexport function getAuthContext(req: Request): { user: User; session: Session } {\n const authReq = req as AuthenticatedRequest;\n if (!authReq.authUser || !authReq.authSession) {\n throw new Error(\"Request is not authenticated\");\n }\n return { user: authReq.authUser, session: authReq.authSession };\n}\n\n/**\n * Express adapter exports\n */\nexport const expressAdapter = {\n createMiddleware: createExpressMiddleware,\n /** @deprecated Use createMiddleware instead */\n middleware,\n isAuthenticated,\n getAuthContext,\n};\n\n// Default export for convenience\nexport default expressAdapter;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/server/nextjs.ts
21
+ var nextjs_exports = {};
22
+ __export(nextjs_exports, {
23
+ createNextJsServer: () => createNextJsServer
24
+ });
25
+ module.exports = __toCommonJS(nextjs_exports);
26
+ var import_server_only = require("server-only");
27
+ var import_next_js = require("better-auth/next-js");
28
+ var import_headers = require("next/headers");
29
+ function createNextJsServer(auth, db) {
30
+ const handler = (0, import_next_js.toNextJsHandler)(auth);
31
+ return {
32
+ /**
33
+ * The underlying BetterAuth instance.
34
+ */
35
+ auth,
36
+ /**
37
+ * Next.js route handler for auth routes.
38
+ * Place this in `app/api/auth/[...auth]/route.ts`
39
+ */
40
+ handler: {
41
+ GET: handler,
42
+ POST: handler
43
+ },
44
+ /**
45
+ * Get session from current request headers.
46
+ * Use in Server Components or Route Handlers.
47
+ */
48
+ getSession: async () => {
49
+ const requestHeaders = await (0, import_headers.headers)();
50
+ return auth.api.getSession({
51
+ headers: requestHeaders
52
+ });
53
+ },
54
+ /**
55
+ * Get session from specific headers.
56
+ * Use when you have direct access to headers.
57
+ */
58
+ getSessionFromHeaders: async (requestHeaders) => {
59
+ return auth.api.getSession({
60
+ headers: requestHeaders
61
+ });
62
+ },
63
+ /**
64
+ * Check if user is authenticated.
65
+ * Use in Server Components.
66
+ */
67
+ isAuthenticated: async () => {
68
+ const requestHeaders = await (0, import_headers.headers)();
69
+ const session = await auth.api.getSession({
70
+ headers: requestHeaders
71
+ });
72
+ return session !== null;
73
+ },
74
+ /**
75
+ * Get the current user or null.
76
+ * Convenience method for Server Components.
77
+ */
78
+ getUser: async () => {
79
+ const requestHeaders = await (0, import_headers.headers)();
80
+ const session = await auth.api.getSession({
81
+ headers: requestHeaders
82
+ });
83
+ return session?.user ?? null;
84
+ },
85
+ /**
86
+ * Wraps a function to ensure the user is authenticated before execution.
87
+ * Injects the user, session, and db into the first argument.
88
+ */
89
+ makeAuthenticatedCall: (fn) => {
90
+ return async (...args) => {
91
+ const requestHeaders = await (0, import_headers.headers)();
92
+ const session = await auth.api.getSession({
93
+ headers: requestHeaders
94
+ });
95
+ if (!session) {
96
+ throw new Error("Unauthorized");
97
+ }
98
+ return fn({ user: session.user, session: session.session, db }, ...args);
99
+ };
100
+ }
101
+ };
102
+ }
103
+ // Annotate the CommonJS export names for ESM import in node:
104
+ 0 && (module.exports = {
105
+ createNextJsServer
106
+ });
107
+ //# sourceMappingURL=nextjs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/nextjs.ts"],"sourcesContent":["import \"server-only\";\nimport { toNextJsHandler } from \"better-auth/next-js\";\nimport { headers } from \"next/headers\";\nimport type { SessionResult, SessionData } from \"../client/types\";\n\n// Type for auth instance created by createAuth\ntype HyleAuth = ReturnType<typeof import(\"better-auth\").betterAuth>;\n// Type for db instance created by createDb \ntype HyleDb = ReturnType<typeof import(\"drizzle-orm/libsql\").drizzle>;\n\n/**\n * Creates Next.js server-side auth utilities (App Router).\n * \n * @param auth - Auth instance created by createAuth()\n * @param db - Database instance created by createDb()\n * @returns Server-side auth utilities for Next.js\n * \n * @example\n * ```typescript\n * // In lib/auth.ts\n * import { createDb, createAuth } from \"hylekit\";\n * import { createNextJsServer } from \"hylekit/nextjs\";\n * \n * const db = createDb({ url: process.env.HYLE_DATABASE_URL!, authToken: process.env.HYLE_DATABASE_AUTH_TOKEN });\n * const auth = createAuth(db, { baseURL: process.env.BETTER_AUTH_URL!, secret: process.env.BETTER_AUTH_SECRET!, ... });\n * \n * export const { handler, getSession, isAuthenticated, getUser, makeAuthenticatedCall } = createNextJsServer(auth, db);\n * ```\n */\nexport function createNextJsServer(auth: HyleAuth, db: HyleDb) {\n const handler = toNextJsHandler(auth);\n\n return {\n /**\n * The underlying BetterAuth instance.\n */\n auth,\n\n /**\n * Next.js route handler for auth routes.\n * Place this in `app/api/auth/[...auth]/route.ts`\n */\n handler: {\n GET: handler,\n POST: handler,\n },\n\n /**\n * Get session from current request headers.\n * Use in Server Components or Route Handlers.\n */\n getSession: async (): Promise<SessionResult> => {\n const requestHeaders = await headers();\n return auth.api.getSession({\n headers: requestHeaders,\n });\n },\n\n /**\n * Get session from specific headers.\n * Use when you have direct access to headers.\n */\n getSessionFromHeaders: async (requestHeaders: Headers): Promise<SessionResult> => {\n return auth.api.getSession({\n headers: requestHeaders,\n });\n },\n\n /**\n * Check if user is authenticated.\n * Use in Server Components.\n */\n isAuthenticated: async (): Promise<boolean> => {\n const requestHeaders = await headers();\n const session = await auth.api.getSession({\n headers: requestHeaders,\n });\n return session !== null;\n },\n\n /**\n * Get the current user or null.\n * Convenience method for Server Components.\n */\n getUser: async () => {\n const requestHeaders = await headers();\n const session = await auth.api.getSession({\n headers: requestHeaders,\n });\n return session?.user ?? null;\n },\n\n /**\n * Wraps a function to ensure the user is authenticated before execution.\n * Injects the user, session, and db into the first argument.\n */\n makeAuthenticatedCall: <TArgs extends any[], TReturn>(\n fn: (ctx: { user: SessionData['user']; session: SessionData['session']; db: typeof db }, ...args: TArgs) => Promise<TReturn>\n ) => {\n return async (...args: TArgs): Promise<TReturn> => {\n const requestHeaders = await headers();\n const session = await auth.api.getSession({\n headers: requestHeaders,\n });\n if (!session) {\n throw new Error(\"Unauthorized\");\n }\n return fn({ user: session.user, session: session.session, db }, ...args);\n }\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAO;AACP,qBAAgC;AAChC,qBAAwB;AA2BjB,SAAS,mBAAmB,MAAgB,IAAY;AAC3D,QAAM,cAAU,gCAAgB,IAAI;AAEpC,SAAO;AAAA;AAAA;AAAA;AAAA,IAIH;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,SAAS;AAAA,MACL,KAAK;AAAA,MACL,MAAM;AAAA,IACV;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,YAAY,YAAoC;AAC5C,YAAM,iBAAiB,UAAM,wBAAQ;AACrC,aAAO,KAAK,IAAI,WAAW;AAAA,QACvB,SAAS;AAAA,MACb,CAAC;AAAA,IACL;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,uBAAuB,OAAO,mBAAoD;AAC9E,aAAO,KAAK,IAAI,WAAW;AAAA,QACvB,SAAS;AAAA,MACb,CAAC;AAAA,IACL;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,iBAAiB,YAA8B;AAC3C,YAAM,iBAAiB,UAAM,wBAAQ;AACrC,YAAM,UAAU,MAAM,KAAK,IAAI,WAAW;AAAA,QACtC,SAAS;AAAA,MACb,CAAC;AACD,aAAO,YAAY;AAAA,IACvB;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,SAAS,YAAY;AACjB,YAAM,iBAAiB,UAAM,wBAAQ;AACrC,YAAM,UAAU,MAAM,KAAK,IAAI,WAAW;AAAA,QACtC,SAAS;AAAA,MACb,CAAC;AACD,aAAO,SAAS,QAAQ;AAAA,IAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,uBAAuB,CACnB,OACC;AACD,aAAO,UAAU,SAAkC;AAC/C,cAAM,iBAAiB,UAAM,wBAAQ;AACrC,cAAM,UAAU,MAAM,KAAK,IAAI,WAAW;AAAA,UACtC,SAAS;AAAA,QACb,CAAC;AACD,YAAI,CAAC,SAAS;AACV,gBAAM,IAAI,MAAM,cAAc;AAAA,QAClC;AACA,eAAO,GAAG,EAAE,MAAM,QAAQ,MAAM,SAAS,QAAQ,SAAS,GAAG,GAAG,GAAG,IAAI;AAAA,MAC3E;AAAA,IACJ;AAAA,EACJ;AACJ;","names":[]}
@@ -0,0 +1,90 @@
1
+ import * as drizzle_orm_libsql from 'drizzle-orm/libsql';
2
+ import * as better_auth from 'better-auth';
3
+ import { S as SessionResult, a as SessionData } from '../types-Wucl0qmN.cjs';
4
+
5
+ type HyleAuth = ReturnType<typeof better_auth.betterAuth>;
6
+ type HyleDb = ReturnType<typeof drizzle_orm_libsql.drizzle>;
7
+ /**
8
+ * Creates Next.js server-side auth utilities (App Router).
9
+ *
10
+ * @param auth - Auth instance created by createAuth()
11
+ * @param db - Database instance created by createDb()
12
+ * @returns Server-side auth utilities for Next.js
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // In lib/auth.ts
17
+ * import { createDb, createAuth } from "hylekit";
18
+ * import { createNextJsServer } from "hylekit/nextjs";
19
+ *
20
+ * const db = createDb({ url: process.env.HYLE_DATABASE_URL!, authToken: process.env.HYLE_DATABASE_AUTH_TOKEN });
21
+ * const auth = createAuth(db, { baseURL: process.env.BETTER_AUTH_URL!, secret: process.env.BETTER_AUTH_SECRET!, ... });
22
+ *
23
+ * export const { handler, getSession, isAuthenticated, getUser, makeAuthenticatedCall } = createNextJsServer(auth, db);
24
+ * ```
25
+ */
26
+ declare function createNextJsServer(auth: HyleAuth, db: HyleDb): {
27
+ /**
28
+ * The underlying BetterAuth instance.
29
+ */
30
+ auth: better_auth.Auth<better_auth.BetterAuthOptions>;
31
+ /**
32
+ * Next.js route handler for auth routes.
33
+ * Place this in `app/api/auth/[...auth]/route.ts`
34
+ */
35
+ handler: {
36
+ GET: {
37
+ GET: (request: Request) => Promise<Response>;
38
+ POST: (request: Request) => Promise<Response>;
39
+ PATCH: (request: Request) => Promise<Response>;
40
+ PUT: (request: Request) => Promise<Response>;
41
+ DELETE: (request: Request) => Promise<Response>;
42
+ };
43
+ POST: {
44
+ GET: (request: Request) => Promise<Response>;
45
+ POST: (request: Request) => Promise<Response>;
46
+ PATCH: (request: Request) => Promise<Response>;
47
+ PUT: (request: Request) => Promise<Response>;
48
+ DELETE: (request: Request) => Promise<Response>;
49
+ };
50
+ };
51
+ /**
52
+ * Get session from current request headers.
53
+ * Use in Server Components or Route Handlers.
54
+ */
55
+ getSession: () => Promise<SessionResult>;
56
+ /**
57
+ * Get session from specific headers.
58
+ * Use when you have direct access to headers.
59
+ */
60
+ getSessionFromHeaders: (requestHeaders: Headers) => Promise<SessionResult>;
61
+ /**
62
+ * Check if user is authenticated.
63
+ * Use in Server Components.
64
+ */
65
+ isAuthenticated: () => Promise<boolean>;
66
+ /**
67
+ * Get the current user or null.
68
+ * Convenience method for Server Components.
69
+ */
70
+ getUser: () => Promise<{
71
+ id: string;
72
+ createdAt: Date;
73
+ updatedAt: Date;
74
+ email: string;
75
+ emailVerified: boolean;
76
+ name: string;
77
+ image?: string | null | undefined | undefined;
78
+ } | null>;
79
+ /**
80
+ * Wraps a function to ensure the user is authenticated before execution.
81
+ * Injects the user, session, and db into the first argument.
82
+ */
83
+ makeAuthenticatedCall: <TArgs extends any[], TReturn>(fn: (ctx: {
84
+ user: SessionData["user"];
85
+ session: SessionData["session"];
86
+ db: typeof db;
87
+ }, ...args: TArgs) => Promise<TReturn>) => (...args: TArgs) => Promise<TReturn>;
88
+ };
89
+
90
+ export { createNextJsServer };
@@ -0,0 +1,90 @@
1
+ import * as drizzle_orm_libsql from 'drizzle-orm/libsql';
2
+ import * as better_auth from 'better-auth';
3
+ import { S as SessionResult, a as SessionData } from '../types-Wucl0qmN.js';
4
+
5
+ type HyleAuth = ReturnType<typeof better_auth.betterAuth>;
6
+ type HyleDb = ReturnType<typeof drizzle_orm_libsql.drizzle>;
7
+ /**
8
+ * Creates Next.js server-side auth utilities (App Router).
9
+ *
10
+ * @param auth - Auth instance created by createAuth()
11
+ * @param db - Database instance created by createDb()
12
+ * @returns Server-side auth utilities for Next.js
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * // In lib/auth.ts
17
+ * import { createDb, createAuth } from "hylekit";
18
+ * import { createNextJsServer } from "hylekit/nextjs";
19
+ *
20
+ * const db = createDb({ url: process.env.HYLE_DATABASE_URL!, authToken: process.env.HYLE_DATABASE_AUTH_TOKEN });
21
+ * const auth = createAuth(db, { baseURL: process.env.BETTER_AUTH_URL!, secret: process.env.BETTER_AUTH_SECRET!, ... });
22
+ *
23
+ * export const { handler, getSession, isAuthenticated, getUser, makeAuthenticatedCall } = createNextJsServer(auth, db);
24
+ * ```
25
+ */
26
+ declare function createNextJsServer(auth: HyleAuth, db: HyleDb): {
27
+ /**
28
+ * The underlying BetterAuth instance.
29
+ */
30
+ auth: better_auth.Auth<better_auth.BetterAuthOptions>;
31
+ /**
32
+ * Next.js route handler for auth routes.
33
+ * Place this in `app/api/auth/[...auth]/route.ts`
34
+ */
35
+ handler: {
36
+ GET: {
37
+ GET: (request: Request) => Promise<Response>;
38
+ POST: (request: Request) => Promise<Response>;
39
+ PATCH: (request: Request) => Promise<Response>;
40
+ PUT: (request: Request) => Promise<Response>;
41
+ DELETE: (request: Request) => Promise<Response>;
42
+ };
43
+ POST: {
44
+ GET: (request: Request) => Promise<Response>;
45
+ POST: (request: Request) => Promise<Response>;
46
+ PATCH: (request: Request) => Promise<Response>;
47
+ PUT: (request: Request) => Promise<Response>;
48
+ DELETE: (request: Request) => Promise<Response>;
49
+ };
50
+ };
51
+ /**
52
+ * Get session from current request headers.
53
+ * Use in Server Components or Route Handlers.
54
+ */
55
+ getSession: () => Promise<SessionResult>;
56
+ /**
57
+ * Get session from specific headers.
58
+ * Use when you have direct access to headers.
59
+ */
60
+ getSessionFromHeaders: (requestHeaders: Headers) => Promise<SessionResult>;
61
+ /**
62
+ * Check if user is authenticated.
63
+ * Use in Server Components.
64
+ */
65
+ isAuthenticated: () => Promise<boolean>;
66
+ /**
67
+ * Get the current user or null.
68
+ * Convenience method for Server Components.
69
+ */
70
+ getUser: () => Promise<{
71
+ id: string;
72
+ createdAt: Date;
73
+ updatedAt: Date;
74
+ email: string;
75
+ emailVerified: boolean;
76
+ name: string;
77
+ image?: string | null | undefined | undefined;
78
+ } | null>;
79
+ /**
80
+ * Wraps a function to ensure the user is authenticated before execution.
81
+ * Injects the user, session, and db into the first argument.
82
+ */
83
+ makeAuthenticatedCall: <TArgs extends any[], TReturn>(fn: (ctx: {
84
+ user: SessionData["user"];
85
+ session: SessionData["session"];
86
+ db: typeof db;
87
+ }, ...args: TArgs) => Promise<TReturn>) => (...args: TArgs) => Promise<TReturn>;
88
+ };
89
+
90
+ export { createNextJsServer };
@@ -0,0 +1,82 @@
1
+ // src/server/nextjs.ts
2
+ import "server-only";
3
+ import { toNextJsHandler } from "better-auth/next-js";
4
+ import { headers } from "next/headers";
5
+ function createNextJsServer(auth, db) {
6
+ const handler = toNextJsHandler(auth);
7
+ return {
8
+ /**
9
+ * The underlying BetterAuth instance.
10
+ */
11
+ auth,
12
+ /**
13
+ * Next.js route handler for auth routes.
14
+ * Place this in `app/api/auth/[...auth]/route.ts`
15
+ */
16
+ handler: {
17
+ GET: handler,
18
+ POST: handler
19
+ },
20
+ /**
21
+ * Get session from current request headers.
22
+ * Use in Server Components or Route Handlers.
23
+ */
24
+ getSession: async () => {
25
+ const requestHeaders = await headers();
26
+ return auth.api.getSession({
27
+ headers: requestHeaders
28
+ });
29
+ },
30
+ /**
31
+ * Get session from specific headers.
32
+ * Use when you have direct access to headers.
33
+ */
34
+ getSessionFromHeaders: async (requestHeaders) => {
35
+ return auth.api.getSession({
36
+ headers: requestHeaders
37
+ });
38
+ },
39
+ /**
40
+ * Check if user is authenticated.
41
+ * Use in Server Components.
42
+ */
43
+ isAuthenticated: async () => {
44
+ const requestHeaders = await headers();
45
+ const session = await auth.api.getSession({
46
+ headers: requestHeaders
47
+ });
48
+ return session !== null;
49
+ },
50
+ /**
51
+ * Get the current user or null.
52
+ * Convenience method for Server Components.
53
+ */
54
+ getUser: async () => {
55
+ const requestHeaders = await headers();
56
+ const session = await auth.api.getSession({
57
+ headers: requestHeaders
58
+ });
59
+ return session?.user ?? null;
60
+ },
61
+ /**
62
+ * Wraps a function to ensure the user is authenticated before execution.
63
+ * Injects the user, session, and db into the first argument.
64
+ */
65
+ makeAuthenticatedCall: (fn) => {
66
+ return async (...args) => {
67
+ const requestHeaders = await headers();
68
+ const session = await auth.api.getSession({
69
+ headers: requestHeaders
70
+ });
71
+ if (!session) {
72
+ throw new Error("Unauthorized");
73
+ }
74
+ return fn({ user: session.user, session: session.session, db }, ...args);
75
+ };
76
+ }
77
+ };
78
+ }
79
+ export {
80
+ createNextJsServer
81
+ };
82
+ //# sourceMappingURL=nextjs.js.map