hylekit 1.0.0 β 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +434 -0
- package/dist/bff/index.cjs +338 -0
- package/dist/bff/index.cjs.map +1 -0
- package/dist/bff/index.d.cts +2 -0
- package/dist/bff/index.d.ts +2 -0
- package/dist/bff/index.js +316 -0
- package/dist/bff/index.js.map +1 -0
- package/dist/client/nextjs.cjs +250 -0
- package/dist/client/nextjs.cjs.map +1 -0
- package/dist/client/nextjs.d.cts +868 -0
- package/dist/client/nextjs.d.ts +868 -0
- package/dist/client/nextjs.js +230 -0
- package/dist/client/nextjs.js.map +1 -0
- package/dist/client/sveltekit.cjs +237 -0
- package/dist/client/sveltekit.cjs.map +1 -0
- package/dist/client/sveltekit.d.cts +844 -0
- package/dist/client/sveltekit.d.ts +844 -0
- package/dist/client/sveltekit.js +217 -0
- package/dist/client/sveltekit.js.map +1 -0
- package/dist/index-DYW73KK3.d.cts +58 -0
- package/dist/index-DYW73KK3.d.ts +58 -0
- package/dist/index.cjs +502 -553
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3266 -1897
- package/dist/index.d.ts +3266 -1897
- package/dist/index.js +488 -535
- package/dist/index.js.map +1 -1
- package/dist/lib/schema.cjs +118 -0
- package/dist/lib/schema.cjs.map +1 -0
- package/dist/lib/schema.d.cts +3 -0
- package/dist/lib/schema.d.ts +3 -0
- package/dist/lib/schema.js +87 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/schema-ph9L8QMm.d.cts +674 -0
- package/dist/schema-ph9L8QMm.d.ts +674 -0
- package/dist/server/express.cjs +243 -0
- package/dist/server/express.cjs.map +1 -0
- package/dist/server/express.d.cts +85 -0
- package/dist/server/express.d.ts +85 -0
- package/dist/server/express.js +219 -0
- package/dist/server/express.js.map +1 -0
- package/dist/types-BHiK1JUX.d.cts +32 -0
- package/dist/types-GOn9sn7-.d.ts +32 -0
- package/package.json +45 -10
package/README.md
ADDED
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
# HyleKit
|
|
2
|
+
|
|
3
|
+
Distributed BetterAuth library for SvelteKit and Next.js with Google OAuth and Turso cloud database.
|
|
4
|
+
|
|
5
|
+
> **Note:** HyleKit provides **only the authentication database**. You will need to provision your own separate database for storing application data.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- π **Google OAuth** - Simple Google login integration
|
|
10
|
+
- π **Distributed Auth** - Each app runs auth locally, sharing a centralized Turso auth database
|
|
11
|
+
- π¦ **Framework Adapters** - First-class support for SvelteKit and Next.js
|
|
12
|
+
- ποΈ **Turso/LibSQL** - Edge-friendly SQLite database for auth
|
|
13
|
+
- π **Session Management** - Automatic session handling with cookies
|
|
14
|
+
- π **BFF Pattern** - Built-in support for Backend-For-Frontend architecture with Express
|
|
15
|
+
|
|
16
|
+
## Database Architecture
|
|
17
|
+
|
|
18
|
+
HyleKit uses a **centralized authentication database** that all your applications connect to. This database stores:
|
|
19
|
+
- User accounts
|
|
20
|
+
- Sessions
|
|
21
|
+
- OAuth tokens
|
|
22
|
+
- Verification tokens
|
|
23
|
+
|
|
24
|
+
**You must provision two databases:**
|
|
25
|
+
|
|
26
|
+
| Database | Purpose | Provided by |
|
|
27
|
+
|----------|---------|-------------|
|
|
28
|
+
| **Hyle Auth Database** | Stores users, sessions, and auth data | HyleKit (shared Turso instance) |
|
|
29
|
+
| **Your Application Database** | Stores your app's business data | You (separate database) |
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
33
|
+
β Your Application β
|
|
34
|
+
ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ€
|
|
35
|
+
β Hyle Auth Database β Your Application Database β
|
|
36
|
+
β (Turso - provided by Hyle) β (Postgres, MySQL, SQLite, etc.) β
|
|
37
|
+
β βββ users β βββ products β
|
|
38
|
+
β βββ sessions β βββ orders β
|
|
39
|
+
β βββ accounts β βββ posts β
|
|
40
|
+
β βββ verification β βββ ... your data β
|
|
41
|
+
ββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> **Important:** Your application database can use any database technology you prefer. HyleKit does not manage or interact with your application dataβonly authentication.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install hylekit
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Environment Variables
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Turso Database
|
|
56
|
+
HYLE_DATABASE_URL=libsql://[db-name]-[org].turso.io
|
|
57
|
+
HYLE_DATABASE_AUTH_TOKEN=your-turso-token
|
|
58
|
+
|
|
59
|
+
# Google OAuth
|
|
60
|
+
GOOGLE_CLIENT_ID=your-google-client-id
|
|
61
|
+
GOOGLE_CLIENT_SECRET=your-google-client-secret
|
|
62
|
+
|
|
63
|
+
# App URL
|
|
64
|
+
PUBLIC_APP_URL=http://localhost:5173 # or your production URL
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Architecture
|
|
68
|
+
|
|
69
|
+
HyleKit supports a BFF (Backend-For-Frontend) architecture:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
73
|
+
β Browser (Client FE) β
|
|
74
|
+
β βββ Uses: hyle.client (signIn, signOut, etc.) β
|
|
75
|
+
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
|
|
76
|
+
β
|
|
77
|
+
βΌ
|
|
78
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
79
|
+
β Next.js / SvelteKit Backend (BFF) β
|
|
80
|
+
β βββ Auth: hyle.server (getSession, handler, etc.) β
|
|
81
|
+
β βββ Calls Express via: hyle.bff (BffClient) β
|
|
82
|
+
β βββ Attaches session as x-hyle-user/x-hyle-session headers β
|
|
83
|
+
βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
|
|
84
|
+
β
|
|
85
|
+
βΌ
|
|
86
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
87
|
+
β Express Backend β
|
|
88
|
+
β βββ Uses: hyle.server.express.middleware() β
|
|
89
|
+
β βββ Parses headers β req.authUser, req.authSession β
|
|
90
|
+
β βββ Optional: DB verification for service-to-service calls β
|
|
91
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## SvelteKit Setup
|
|
97
|
+
|
|
98
|
+
### 1. Create Auth Route Handler
|
|
99
|
+
|
|
100
|
+
Create the auth API route to handle authentication requests:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// src/routes/api/auth/[...auth]/+server.ts
|
|
104
|
+
import hyle from "hylekit";
|
|
105
|
+
|
|
106
|
+
export const { GET, POST } = hyle.server.sveltekit.handler;
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2. Add Session Hook
|
|
110
|
+
|
|
111
|
+
Add the handle hook to populate session data in `event.locals`:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// src/hooks.server.ts
|
|
115
|
+
import hyle from "hylekit";
|
|
116
|
+
|
|
117
|
+
export const handle = hyle.server.sveltekit.createHandle();
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 3. Extend App.Locals Types
|
|
121
|
+
|
|
122
|
+
Update your type definitions to include session data:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// src/app.d.ts
|
|
126
|
+
import type { SessionResult, UserInfo } from "hylekit";
|
|
127
|
+
|
|
128
|
+
declare global {
|
|
129
|
+
namespace App {
|
|
130
|
+
interface Locals {
|
|
131
|
+
session: SessionResult;
|
|
132
|
+
user: UserInfo | null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export {};
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 4. Use in Pages
|
|
141
|
+
|
|
142
|
+
Access session data in your server load functions:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// src/routes/+page.server.ts
|
|
146
|
+
import type { PageServerLoad } from "./$types";
|
|
147
|
+
|
|
148
|
+
export const load: PageServerLoad = async ({ locals }) => {
|
|
149
|
+
return {
|
|
150
|
+
user: locals.user,
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```svelte
|
|
156
|
+
<!-- src/routes/+page.svelte -->
|
|
157
|
+
<script lang="ts">
|
|
158
|
+
export let data;
|
|
159
|
+
</script>
|
|
160
|
+
|
|
161
|
+
{#if data.user}
|
|
162
|
+
<p>Welcome, {data.user.name}!</p>
|
|
163
|
+
<a href="/api/auth/sign-out">Sign out</a>
|
|
164
|
+
{:else}
|
|
165
|
+
<a href="/api/auth/sign-in/google">Sign in with Google</a>
|
|
166
|
+
{/if}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Next.js Setup (App Router)
|
|
172
|
+
|
|
173
|
+
### 1. Create Auth Route Handler
|
|
174
|
+
|
|
175
|
+
Create the auth API route to handle authentication requests:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
// app/api/auth/[...auth]/route.ts
|
|
179
|
+
import hyle from "hylekit";
|
|
180
|
+
|
|
181
|
+
export const { GET, POST } = hyle.server.nextjs.handler;
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 2. Use in Server Components
|
|
185
|
+
|
|
186
|
+
Access session data directly in your server components:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// app/page.tsx
|
|
190
|
+
import hyle from "hylekit";
|
|
191
|
+
|
|
192
|
+
export default async function Page() {
|
|
193
|
+
const session = await hyle.server.nextjs.getSession();
|
|
194
|
+
|
|
195
|
+
if (!session) {
|
|
196
|
+
return (
|
|
197
|
+
<a href="/api/auth/sign-in/google">Sign in with Google</a>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<div>
|
|
203
|
+
<p>Welcome, {session.user.name}!</p>
|
|
204
|
+
<a href="/api/auth/sign-out">Sign out</a>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 3. Protected Routes
|
|
211
|
+
|
|
212
|
+
Use the auth helpers to protect routes:
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// app/dashboard/page.tsx
|
|
216
|
+
import hyle from "hylekit";
|
|
217
|
+
import { redirect } from "next/navigation";
|
|
218
|
+
|
|
219
|
+
export default async function DashboardPage() {
|
|
220
|
+
const isAuth = await hyle.server.nextjs.isAuthenticated();
|
|
221
|
+
|
|
222
|
+
if (!isAuth) {
|
|
223
|
+
redirect("/api/auth/sign-in/google");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const user = await hyle.server.nextjs.getUser();
|
|
227
|
+
|
|
228
|
+
return <p>Dashboard for {user?.name}</p>;
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## BFF Pattern with Express
|
|
235
|
+
|
|
236
|
+
### 1. Setup Express Middleware
|
|
237
|
+
|
|
238
|
+
Configure the Express middleware to parse authenticated requests:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// express-app/src/app.ts
|
|
242
|
+
import express from "express";
|
|
243
|
+
import hyle from "hylekit";
|
|
244
|
+
|
|
245
|
+
const app = express();
|
|
246
|
+
|
|
247
|
+
// Option 1: Trust headers from BFF (internal calls only)
|
|
248
|
+
app.use(hyle.server.express.middleware({
|
|
249
|
+
unauthenticatedRoutes: ["/health", "/public/*"],
|
|
250
|
+
}));
|
|
251
|
+
|
|
252
|
+
// Option 2: Verify sessions against DB (for service-to-service calls)
|
|
253
|
+
app.use(hyle.server.express.middleware({
|
|
254
|
+
unauthenticatedRoutes: ["/health", "/public/*"],
|
|
255
|
+
verifySession: true, // Checks session in Turso DB
|
|
256
|
+
}));
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### 2. Access Auth Context in Routes
|
|
260
|
+
|
|
261
|
+
Use `req.authUser` and `req.authSession` in your route handlers:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import type { AuthenticatedRequest } from "hylekit";
|
|
265
|
+
|
|
266
|
+
app.get("/api/profile", (req: AuthenticatedRequest, res) => {
|
|
267
|
+
// authUser is always available on authenticated routes
|
|
268
|
+
res.json({
|
|
269
|
+
userId: req.authUser.id,
|
|
270
|
+
email: req.authUser.email,
|
|
271
|
+
name: req.authUser.name,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
app.post("/api/settings", (req: AuthenticatedRequest, res) => {
|
|
276
|
+
// Access full session data
|
|
277
|
+
console.log("Session expires:", req.authSession.expiresAt);
|
|
278
|
+
|
|
279
|
+
// Your business logic here
|
|
280
|
+
res.json({ success: true });
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 3. Using Helper Functions
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { isAuthenticated, getAuthContext } from "hylekit";
|
|
288
|
+
|
|
289
|
+
// Type guard for optional auth routes
|
|
290
|
+
app.get("/api/greeting", (req, res) => {
|
|
291
|
+
if (isAuthenticated(req)) {
|
|
292
|
+
res.json({ message: `Hello, ${req.authUser.name}!` });
|
|
293
|
+
} else {
|
|
294
|
+
res.json({ message: "Hello, guest!" });
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Get auth context with error handling
|
|
299
|
+
app.post("/api/order", (req, res) => {
|
|
300
|
+
try {
|
|
301
|
+
const { user, session } = getAuthContext(req);
|
|
302
|
+
// Proceed with authenticated user
|
|
303
|
+
} catch (e) {
|
|
304
|
+
res.status(401).json({ error: "Not authenticated" });
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### 4. Call Express from Next.js/SvelteKit
|
|
310
|
+
|
|
311
|
+
Use the BFF client to make authenticated calls from your frontend backend:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// Next.js: app/api/data/route.ts
|
|
315
|
+
import { createNextJsBff } from "hylekit";
|
|
316
|
+
|
|
317
|
+
const bff = createNextJsBff(process.env.EXPRESS_API_URL!);
|
|
318
|
+
|
|
319
|
+
export async function GET() {
|
|
320
|
+
// Session is automatically attached to the request
|
|
321
|
+
const data = await bff.get("/api/profile");
|
|
322
|
+
return Response.json(data);
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// SvelteKit: src/routes/api/data/+server.ts
|
|
328
|
+
import { createSvelteKitBff } from "hylekit";
|
|
329
|
+
import type { RequestHandler } from "./$types";
|
|
330
|
+
|
|
331
|
+
const bff = createSvelteKitBff(process.env.EXPRESS_API_URL!);
|
|
332
|
+
|
|
333
|
+
export const GET: RequestHandler = async (event) => {
|
|
334
|
+
// Use .with(event) to bind the request context
|
|
335
|
+
const data = await bff.with(event).get("/api/profile");
|
|
336
|
+
return new Response(JSON.stringify(data));
|
|
337
|
+
};
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Middleware Options
|
|
341
|
+
|
|
342
|
+
| Option | Type | Default | Description |
|
|
343
|
+
|--------|------|---------|-------------|
|
|
344
|
+
| `unauthenticatedRoutes` | `string[]` | `[]` | Routes that skip authentication |
|
|
345
|
+
| `verifySession` | `boolean` | `false` | Verify session against DB (for service-to-service) |
|
|
346
|
+
| `required` | `boolean` | `true` | Return 401 for unauthenticated requests |
|
|
347
|
+
|
|
348
|
+
### Route Pattern Examples
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
unauthenticatedRoutes: [
|
|
352
|
+
"/health", // Exact match
|
|
353
|
+
"/public/*", // Matches /public/anything (single level)
|
|
354
|
+
"/api/webhooks/**", // Matches /api/webhooks/a/b/c (deep)
|
|
355
|
+
]
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Database Schema
|
|
361
|
+
|
|
362
|
+
HyleKit uses Drizzle ORM. You can import the schema definitions for use with Drizzle Kit or migration tools.
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
// Import all schema definitions
|
|
366
|
+
import hyle from "hylekit";
|
|
367
|
+
|
|
368
|
+
const { user, session, account, verification } = hyle.schema;
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## API Reference
|
|
374
|
+
|
|
375
|
+
The library exports a default `hyle` object containing:
|
|
376
|
+
|
|
377
|
+
### `hyle.server`
|
|
378
|
+
|
|
379
|
+
#### `hyle.server.sveltekit`
|
|
380
|
+
- `handler`: `{ GET, POST }` route handlers.
|
|
381
|
+
- `createHandle()`: Creates a SvelteKit handle hook.
|
|
382
|
+
- `getSession(event)`: Get session from request event.
|
|
383
|
+
- `isAuthenticated(event)`: Check if user is authenticated.
|
|
384
|
+
- `makeAuthenticatedCall(fn)`: Wrapper to ensure authentication.
|
|
385
|
+
|
|
386
|
+
#### `hyle.server.nextjs`
|
|
387
|
+
- `handler`: `{ GET, POST }` route handlers.
|
|
388
|
+
- `getSession()`: Get session from current request headers.
|
|
389
|
+
- `isAuthenticated()`: Check if user is authenticated.
|
|
390
|
+
- `getUser()`: Get current user object.
|
|
391
|
+
- `makeAuthenticatedCall(fn)`: Wrapper to ensure authentication.
|
|
392
|
+
|
|
393
|
+
#### `hyle.server.express`
|
|
394
|
+
- `middleware(options)`: Express middleware for session verification.
|
|
395
|
+
- `isAuthenticated(req)`: Type guard to check if request is authenticated.
|
|
396
|
+
- `getAuthContext(req)`: Get `{ user, session }` from request (throws if not authenticated).
|
|
397
|
+
|
|
398
|
+
### `hyle.client`
|
|
399
|
+
|
|
400
|
+
#### `hyle.client.sveltekit`
|
|
401
|
+
- `login`: Alias for `signIn`.
|
|
402
|
+
- All `better-auth/svelte` client methods.
|
|
403
|
+
|
|
404
|
+
#### `hyle.client.nextjs`
|
|
405
|
+
- `login`: Alias for `signIn`.
|
|
406
|
+
- All `better-auth/react` client methods.
|
|
407
|
+
|
|
408
|
+
### `hyle.bff`
|
|
409
|
+
|
|
410
|
+
#### `hyle.bff.createNextJsBff(config)`
|
|
411
|
+
Creates a BFF client for Next.js that automatically attaches session headers.
|
|
412
|
+
|
|
413
|
+
#### `hyle.bff.createSvelteKitBff(config)`
|
|
414
|
+
Creates a BFF client for SvelteKit that automatically attaches session headers.
|
|
415
|
+
|
|
416
|
+
### Types
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import type {
|
|
420
|
+
SessionResult,
|
|
421
|
+
SessionData,
|
|
422
|
+
UserInfo,
|
|
423
|
+
Session,
|
|
424
|
+
User,
|
|
425
|
+
BffClientConfig,
|
|
426
|
+
RequestOptions,
|
|
427
|
+
AuthenticatedRequest,
|
|
428
|
+
MiddlewareOptions,
|
|
429
|
+
} from "hylekit";
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## License
|
|
433
|
+
|
|
434
|
+
ISC
|