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
package/dist/index.js CHANGED
@@ -5,13 +5,10 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/lib/auth.ts
8
+ import "server-only";
8
9
  import { betterAuth } from "better-auth";
9
10
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
10
11
 
11
- // src/lib/db.ts
12
- import { drizzle } from "drizzle-orm/libsql";
13
- import { createClient } from "@libsql/client";
14
-
15
12
  // src/lib/schema.ts
16
13
  var schema_exports = {};
17
14
  __export(schema_exports, {
@@ -100,209 +97,211 @@ var accountRelations = relations(account, ({ one }) => ({
100
97
  })
101
98
  }));
102
99
 
103
- // src/lib/db.ts
104
- var client = createClient({
105
- url: process.env.DATABASE_URL,
106
- authToken: process.env.DATABASE_AUTH_TOKEN
107
- });
108
- var db = drizzle(client, { schema: schema_exports });
109
-
110
100
  // src/lib/auth.ts
111
- var auth = betterAuth({
112
- database: drizzleAdapter(db, {
113
- provider: "sqlite",
114
- schema: {
115
- ...schema_exports
116
- }
117
- }),
118
- baseURL: process.env.BETTER_AUTH_URL || process.env.PUBLIC_APP_URL || process.env.NEXT_PUBLIC_APP_URL,
119
- secret: process.env.BETTER_AUTH_SECRET,
120
- trustedOrigins: process.env.TRUSTED_ORIGINS ? process.env.TRUSTED_ORIGINS.split(",") : void 0,
121
- socialProviders: {
122
- google: {
123
- clientId: process.env.GOOGLE_CLIENT_ID || "",
124
- clientSecret: process.env.GOOGLE_CLIENT_SECRET || ""
125
- }
126
- },
127
- session: {
128
- expiresIn: 60 * 60 * 24 * 7,
101
+ function assertServerOnly(configName) {
102
+ if (typeof window !== "undefined") {
103
+ throw new Error(
104
+ `[hylekit] SECURITY ERROR: "${configName}" contains secrets and must not be used on the client side. Only call ${configName}() in server-side code (e.g., API routes, server components, +page.server.ts).`
105
+ );
106
+ }
107
+ }
108
+ function createAuth(db, config) {
109
+ assertServerOnly("createAuth");
110
+ const sessionConfig = {
111
+ expiresIn: config.session?.expiresIn ?? 60 * 60 * 24 * 7,
129
112
  // 7 days
130
- updateAge: 60 * 60 * 24,
131
- // Update session every 24 hours
113
+ updateAge: config.session?.updateAge ?? 60 * 60 * 24,
114
+ // 24 hours
132
115
  cookieCache: {
133
- enabled: true,
134
- maxAge: 60 * 5
116
+ enabled: config.session?.cookieCache?.enabled ?? true,
117
+ maxAge: config.session?.cookieCache?.maxAge ?? 60 * 5
135
118
  // 5 minutes
136
119
  }
120
+ };
121
+ return betterAuth({
122
+ database: drizzleAdapter(db, {
123
+ provider: "sqlite",
124
+ schema: {
125
+ ...schema_exports
126
+ }
127
+ }),
128
+ baseURL: config.baseURL,
129
+ secret: config.secret,
130
+ trustedOrigins: config.trustedOrigins,
131
+ socialProviders: config.google ? {
132
+ google: {
133
+ clientId: config.google.clientId,
134
+ clientSecret: config.google.clientSecret
135
+ }
136
+ } : void 0,
137
+ session: sessionConfig
138
+ });
139
+ }
140
+
141
+ // src/lib/db.ts
142
+ import "server-only";
143
+ import { drizzle } from "drizzle-orm/libsql";
144
+ import { createClient } from "@libsql/client";
145
+ function assertServerOnly2(configName) {
146
+ if (typeof window !== "undefined") {
147
+ throw new Error(
148
+ `[hylekit] SECURITY ERROR: "${configName}" contains secrets and must not be used on the client side. Only call ${configName}() in server-side code (e.g., API routes, server components, +page.server.ts).`
149
+ );
137
150
  }
138
- });
151
+ }
152
+ function createDb(config) {
153
+ assertServerOnly2("createDb");
154
+ const client = createClient({
155
+ url: config.url,
156
+ authToken: config.authToken
157
+ });
158
+ return drizzle(client, { schema: schema_exports });
159
+ }
139
160
 
140
- // src/client/sveltekit.ts
161
+ // src/server/sveltekit.ts
162
+ import "server-only";
141
163
  import { toSvelteKitHandler } from "better-auth/svelte-kit";
142
- import { createAuthClient } from "better-auth/svelte";
143
- var handler = toSvelteKitHandler(auth);
144
- var authClient = createAuthClient();
145
- var client2 = {
146
- ...authClient,
147
- /**
148
- * Alias for signIn.
149
- */
150
- login: authClient.signIn
151
- };
152
- var server = {
153
- /**
154
- * The underlying BetterAuth instance.
155
- */
156
- auth,
157
- /**
158
- * SvelteKit request handler for auth routes.
159
- * Place this in `src/routes/api/auth/[...auth]/+server.ts`
160
- */
161
- handler: {
162
- GET: handler,
163
- POST: handler
164
- },
165
- /**
166
- * Creates a SvelteKit handle hook for session management.
167
- */
168
- createHandle: () => {
169
- return async ({ event, resolve }) => {
170
- const session2 = await auth.api.getSession({
164
+ function createSvelteKitServer(auth, db) {
165
+ const handler = toSvelteKitHandler(auth);
166
+ return {
167
+ /**
168
+ * The underlying BetterAuth instance.
169
+ */
170
+ auth,
171
+ /**
172
+ * SvelteKit request handler for auth routes.
173
+ * Place this in `src/routes/api/auth/[...auth]/+server.ts`
174
+ */
175
+ handler: {
176
+ GET: handler,
177
+ POST: handler
178
+ },
179
+ /**
180
+ * Creates a SvelteKit handle hook for session management.
181
+ */
182
+ createHandle: () => {
183
+ return async ({ event, resolve }) => {
184
+ const session2 = await auth.api.getSession({
185
+ headers: event.request.headers
186
+ });
187
+ event.locals.session = session2;
188
+ event.locals.user = session2?.user ?? null;
189
+ return resolve(event);
190
+ };
191
+ },
192
+ /**
193
+ * Get session from request event.
194
+ */
195
+ getSession: async (event) => {
196
+ return auth.api.getSession({
171
197
  headers: event.request.headers
172
198
  });
173
- event.locals.session = session2;
174
- event.locals.user = session2?.user ?? null;
175
- return resolve(event);
176
- };
177
- },
178
- /**
179
- * Get session from request event.
180
- */
181
- getSession: async (event) => {
182
- return auth.api.getSession({
183
- headers: event.request.headers
184
- });
185
- },
186
- /**
187
- * Check if user is authenticated.
188
- */
189
- isAuthenticated: async (event) => {
190
- const session2 = await auth.api.getSession({
191
- headers: event.request.headers
192
- });
193
- return session2 !== null;
194
- },
195
- /**
196
- * Wraps a function to ensure the user is authenticated before execution.
197
- * Injects the user, session, and db into the first argument.
198
- */
199
- makeAuthenticatedCall: (fn) => {
200
- return async (event, ...args) => {
199
+ },
200
+ /**
201
+ * Check if user is authenticated.
202
+ */
203
+ isAuthenticated: async (event) => {
201
204
  const session2 = await auth.api.getSession({
202
205
  headers: event.request.headers
203
206
  });
204
- if (!session2) {
205
- throw new Error("Unauthorized");
206
- }
207
- return fn({ user: session2.user, session: session2.session, db, event }, ...args);
208
- };
209
- }
210
- };
207
+ return session2 !== null;
208
+ },
209
+ /**
210
+ * Wraps a function to ensure the user is authenticated before execution.
211
+ * Injects the user, session, and db into the first argument.
212
+ */
213
+ makeAuthenticatedCall: (fn) => {
214
+ return async (event, ...args) => {
215
+ const session2 = await auth.api.getSession({
216
+ headers: event.request.headers
217
+ });
218
+ if (!session2) {
219
+ throw new Error("Unauthorized");
220
+ }
221
+ return fn({ user: session2.user, session: session2.session, db, event }, ...args);
222
+ };
223
+ }
224
+ };
225
+ }
211
226
 
212
- // src/client/nextjs.ts
227
+ // src/server/nextjs.ts
228
+ import "server-only";
213
229
  import { toNextJsHandler } from "better-auth/next-js";
214
- import { createAuthClient as createAuthClient2 } from "better-auth/react";
215
230
  import { headers } from "next/headers";
216
- var handler2 = toNextJsHandler(auth);
217
- var authClient2 = createAuthClient2();
218
- var client3 = {
219
- ...authClient2,
220
- /**
221
- * Alias for signIn.
222
- */
223
- login: authClient2.signIn
224
- };
225
- var server2 = {
226
- /**
227
- * The underlying BetterAuth instance.
228
- */
229
- auth,
230
- /**
231
- * Next.js route handler for auth routes.
232
- * Place this in `app/api/auth/[...auth]/route.ts`
233
- */
234
- handler: {
235
- GET: handler2,
236
- POST: handler2
237
- },
238
- /**
239
- * Get session from current request headers.
240
- * Use in Server Components or Route Handlers.
241
- */
242
- getSession: async () => {
243
- const requestHeaders = await headers();
244
- return auth.api.getSession({
245
- headers: requestHeaders
246
- });
247
- },
248
- /**
249
- * Get session from specific headers.
250
- * Use when you have direct access to headers.
251
- */
252
- getSessionFromHeaders: async (requestHeaders) => {
253
- return auth.api.getSession({
254
- headers: requestHeaders
255
- });
256
- },
257
- /**
258
- * Check if user is authenticated.
259
- * Use in Server Components.
260
- */
261
- isAuthenticated: async () => {
262
- const requestHeaders = await headers();
263
- const session2 = await auth.api.getSession({
264
- headers: requestHeaders
265
- });
266
- return session2 !== null;
267
- },
268
- /**
269
- * Get the current user or null.
270
- * Convenience method for Server Components.
271
- */
272
- getUser: async () => {
273
- const requestHeaders = await headers();
274
- const session2 = await auth.api.getSession({
275
- headers: requestHeaders
276
- });
277
- return session2?.user ?? null;
278
- },
279
- /**
280
- * Wraps a function to ensure the user is authenticated before execution.
281
- * Injects the user, session, and db into the first argument.
282
- */
283
- makeAuthenticatedCall: (fn) => {
284
- return async (...args) => {
231
+ function createNextJsServer(auth, db) {
232
+ const handler = toNextJsHandler(auth);
233
+ return {
234
+ /**
235
+ * The underlying BetterAuth instance.
236
+ */
237
+ auth,
238
+ /**
239
+ * Next.js route handler for auth routes.
240
+ * Place this in `app/api/auth/[...auth]/route.ts`
241
+ */
242
+ handler: {
243
+ GET: handler,
244
+ POST: handler
245
+ },
246
+ /**
247
+ * Get session from current request headers.
248
+ * Use in Server Components or Route Handlers.
249
+ */
250
+ getSession: async () => {
251
+ const requestHeaders = await headers();
252
+ return auth.api.getSession({
253
+ headers: requestHeaders
254
+ });
255
+ },
256
+ /**
257
+ * Get session from specific headers.
258
+ * Use when you have direct access to headers.
259
+ */
260
+ getSessionFromHeaders: async (requestHeaders) => {
261
+ return auth.api.getSession({
262
+ headers: requestHeaders
263
+ });
264
+ },
265
+ /**
266
+ * Check if user is authenticated.
267
+ * Use in Server Components.
268
+ */
269
+ isAuthenticated: async () => {
285
270
  const requestHeaders = await headers();
286
271
  const session2 = await auth.api.getSession({
287
272
  headers: requestHeaders
288
273
  });
289
- if (!session2) {
290
- throw new Error("Unauthorized");
291
- }
292
- return fn({ user: session2.user, session: session2.session, db }, ...args);
293
- };
294
- }
295
- };
296
-
297
- // src/client/index.ts
298
- var client4 = {
299
- sveltekit: client2,
300
- nextjs: client3
301
- };
302
- var server3 = {
303
- sveltekit: server,
304
- nextjs: server2
305
- };
274
+ return session2 !== null;
275
+ },
276
+ /**
277
+ * Get the current user or null.
278
+ * Convenience method for Server Components.
279
+ */
280
+ getUser: async () => {
281
+ const requestHeaders = await headers();
282
+ const session2 = await auth.api.getSession({
283
+ headers: requestHeaders
284
+ });
285
+ return session2?.user ?? null;
286
+ },
287
+ /**
288
+ * Wraps a function to ensure the user is authenticated before execution.
289
+ * Injects the user, session, and db into the first argument.
290
+ */
291
+ makeAuthenticatedCall: (fn) => {
292
+ return async (...args) => {
293
+ const requestHeaders = await headers();
294
+ const session2 = await auth.api.getSession({
295
+ headers: requestHeaders
296
+ });
297
+ if (!session2) {
298
+ throw new Error("Unauthorized");
299
+ }
300
+ return fn({ user: session2.user, session: session2.session, db }, ...args);
301
+ };
302
+ }
303
+ };
304
+ }
306
305
 
307
306
  // src/bff/client.ts
308
307
  var BffClientBase = class {
@@ -348,13 +347,14 @@ var BffClientBase = class {
348
347
  // src/bff/nextjs.ts
349
348
  import { headers as headers2 } from "next/headers";
350
349
  var NextJsBffClient = class extends BffClientBase {
351
- constructor(config) {
350
+ constructor(auth, config) {
352
351
  super(config);
352
+ this.auth = auth;
353
353
  }
354
354
  async getAuthHeaders() {
355
355
  try {
356
356
  const requestHeaders = await headers2();
357
- const sessionData = await auth.api.getSession({
357
+ const sessionData = await this.auth.api.getSession({
358
358
  headers: requestHeaders
359
359
  });
360
360
  if (!sessionData) return {};
@@ -420,9 +420,9 @@ var NextJsBffClient = class extends BffClientBase {
420
420
  });
421
421
  }
422
422
  };
423
- var createNextJsBff = (baseUrlOrConfig) => {
423
+ var createNextJsBff = (auth, baseUrlOrConfig) => {
424
424
  const config = typeof baseUrlOrConfig === "string" ? { baseUrl: baseUrlOrConfig } : baseUrlOrConfig;
425
- return new NextJsBffClient(config);
425
+ return new NextJsBffClient(auth, config);
426
426
  };
427
427
 
428
428
  // src/bff/sveltekit.ts
@@ -495,76 +495,84 @@ function isUnauthenticatedRoute(path, patterns) {
495
495
  }
496
496
  return false;
497
497
  }
498
- var middleware = (options = {}) => {
499
- const {
500
- unauthenticatedRoutes = [],
501
- verifySession = false,
502
- required = true
503
- } = options;
504
- return async (req, res, next) => {
505
- const authReq = req;
506
- if (isUnauthenticatedRoute(req.path, unauthenticatedRoutes)) {
507
- return next();
498
+ var createExpressMiddleware = (db) => {
499
+ return (options = {}) => {
500
+ const {
501
+ unauthenticatedRoutes = [],
502
+ verifySession = false,
503
+ required = true
504
+ } = options;
505
+ if (verifySession && !db) {
506
+ throw new Error(
507
+ "[hylekit] CONFIGURATION ERROR: verifySession requires a database instance. Pass a db instance to createExpressMiddleware(db)."
508
+ );
508
509
  }
509
- try {
510
- const userHeader = req.headers["x-hyle-user"];
511
- const sessionHeader = req.headers["x-hyle-session"];
512
- if (!sessionHeader || typeof sessionHeader !== "string") {
513
- if (required) {
514
- return res.status(401).json({ error: "Unauthorized" });
515
- }
510
+ return async (req, res, next) => {
511
+ const authReq = req;
512
+ if (isUnauthenticatedRoute(req.path, unauthenticatedRoutes)) {
516
513
  return next();
517
514
  }
518
- const sessionData = JSON.parse(
519
- Buffer.from(sessionHeader, "base64").toString("utf-8")
520
- );
521
- if (verifySession) {
522
- const result = await db.select({
523
- session,
524
- user
525
- }).from(session).innerJoin(user, eq(session.userId, user.id)).where(
526
- and(
527
- eq(session.id, sessionData.id),
528
- gt(session.expiresAt, /* @__PURE__ */ new Date())
529
- )
530
- ).limit(1);
531
- if (result.length === 0) {
515
+ try {
516
+ const userHeader = req.headers["x-hyle-user"];
517
+ const sessionHeader = req.headers["x-hyle-session"];
518
+ if (!sessionHeader || typeof sessionHeader !== "string") {
532
519
  if (required) {
533
- return res.status(401).json({ error: "Invalid or expired session" });
520
+ return res.status(401).json({ error: "Unauthorized" });
534
521
  }
535
522
  return next();
536
523
  }
537
- authReq.authUser = result[0].user;
538
- authReq.authSession = result[0].session;
539
- authReq.user = authReq.authUser;
540
- authReq.session = authReq.authSession;
541
- return next();
542
- }
543
- let userData;
544
- if (userHeader && typeof userHeader === "string") {
545
- userData = JSON.parse(
546
- Buffer.from(userHeader, "base64").toString("utf-8")
524
+ const sessionData = JSON.parse(
525
+ Buffer.from(sessionHeader, "base64").toString("utf-8")
547
526
  );
527
+ if (verifySession && db) {
528
+ const result = await db.select({
529
+ session,
530
+ user
531
+ }).from(session).innerJoin(user, eq(session.userId, user.id)).where(
532
+ and(
533
+ eq(session.id, sessionData.id),
534
+ gt(session.expiresAt, /* @__PURE__ */ new Date())
535
+ )
536
+ ).limit(1);
537
+ if (result.length === 0) {
538
+ if (required) {
539
+ return res.status(401).json({ error: "Invalid or expired session" });
540
+ }
541
+ return next();
542
+ }
543
+ authReq.authUser = result[0].user;
544
+ authReq.authSession = result[0].session;
545
+ authReq.user = authReq.authUser;
546
+ authReq.session = authReq.authSession;
547
+ return next();
548
+ }
549
+ let userData;
550
+ if (userHeader && typeof userHeader === "string") {
551
+ userData = JSON.parse(
552
+ Buffer.from(userHeader, "base64").toString("utf-8")
553
+ );
554
+ }
555
+ if (!userData && required) {
556
+ return res.status(401).json({ error: "Unauthorized" });
557
+ }
558
+ if (userData) {
559
+ authReq.authUser = userData;
560
+ authReq.authSession = sessionData;
561
+ authReq.user = authReq.authUser;
562
+ authReq.session = authReq.authSession;
563
+ }
564
+ next();
565
+ } catch (error) {
566
+ console.error("[hyle] Auth middleware error:", error);
567
+ if (required) {
568
+ return res.status(401).json({ error: "Authentication failed" });
569
+ }
570
+ next();
548
571
  }
549
- if (!userData && required) {
550
- return res.status(401).json({ error: "Unauthorized" });
551
- }
552
- if (userData) {
553
- authReq.authUser = userData;
554
- authReq.authSession = sessionData;
555
- authReq.user = authReq.authUser;
556
- authReq.session = authReq.authSession;
557
- }
558
- next();
559
- } catch (error) {
560
- console.error("[hyle] Auth middleware error:", error);
561
- if (required) {
562
- return res.status(401).json({ error: "Authentication failed" });
563
- }
564
- next();
565
- }
572
+ };
566
573
  };
567
574
  };
575
+ var middleware = createExpressMiddleware();
568
576
  function isAuthenticated(req) {
569
577
  return !!req.authUser;
570
578
  }
@@ -576,6 +584,8 @@ function getAuthContext(req) {
576
584
  return { user: authReq.authUser, session: authReq.authSession };
577
585
  }
578
586
  var expressAdapter = {
587
+ createMiddleware: createExpressMiddleware,
588
+ /** @deprecated Use createMiddleware instead */
579
589
  middleware,
580
590
  isAuthenticated,
581
591
  getAuthContext
@@ -587,12 +597,12 @@ var bff = {
587
597
  createSvelteKitBff
588
598
  };
589
599
  var hyle = {
590
- auth,
591
- db,
600
+ createDb,
601
+ createAuth,
592
602
  schema: schema_exports,
593
- client: client4,
594
603
  server: {
595
- ...server3,
604
+ createSvelteKitServer,
605
+ createNextJsServer,
596
606
  express: expressAdapter
597
607
  },
598
608
  bff
@@ -600,18 +610,20 @@ var hyle = {
600
610
  var src_default = hyle;
601
611
  export {
602
612
  account,
603
- auth,
604
613
  bff,
605
- client4 as client,
614
+ createAuth,
615
+ createDb,
616
+ createExpressMiddleware,
606
617
  createNextJsBff,
618
+ createNextJsServer,
607
619
  createSvelteKitBff,
608
- db,
620
+ createSvelteKitServer,
609
621
  src_default as default,
610
622
  expressAdapter as express,
611
623
  middleware as expressMiddleware,
612
624
  getAuthContext,
613
625
  isAuthenticated,
614
- server3 as server,
626
+ schema_exports as schema,
615
627
  session,
616
628
  user,
617
629
  verification