miragedev-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +393 -0
  3. package/dist/auth/biometric.cjs +85 -0
  4. package/dist/auth/biometric.d.cts +7 -0
  5. package/dist/auth/biometric.d.ts +7 -0
  6. package/dist/auth/biometric.js +81 -0
  7. package/dist/auth/client.cjs +44 -0
  8. package/dist/auth/client.d.cts +12 -0
  9. package/dist/auth/client.d.ts +12 -0
  10. package/dist/auth/client.js +40 -0
  11. package/dist/auth/index.cjs +17 -0
  12. package/dist/auth/index.d.cts +6 -0
  13. package/dist/auth/index.d.ts +6 -0
  14. package/dist/auth/index.js +4 -0
  15. package/dist/auth/middleware.cjs +37 -0
  16. package/dist/auth/middleware.d.cts +10 -0
  17. package/dist/auth/middleware.d.ts +10 -0
  18. package/dist/auth/middleware.js +35 -0
  19. package/dist/auth-BC8JI28z.d.cts +22 -0
  20. package/dist/auth-BC8JI28z.d.ts +22 -0
  21. package/dist/billing/client.cjs +43 -0
  22. package/dist/billing/client.d.cts +11 -0
  23. package/dist/billing/client.d.ts +11 -0
  24. package/dist/billing/client.js +40 -0
  25. package/dist/billing/index.cjs +139 -0
  26. package/dist/billing/index.d.cts +12 -0
  27. package/dist/billing/index.d.ts +12 -0
  28. package/dist/billing/index.js +130 -0
  29. package/dist/billing/mobile.cjs +81 -0
  30. package/dist/billing/mobile.d.cts +17 -0
  31. package/dist/billing/mobile.d.ts +17 -0
  32. package/dist/billing/mobile.js +74 -0
  33. package/dist/billing/webhook.cjs +84 -0
  34. package/dist/billing/webhook.d.cts +19 -0
  35. package/dist/billing/webhook.d.ts +19 -0
  36. package/dist/billing/webhook.js +78 -0
  37. package/dist/billing-Bv2V7KWF.d.cts +23 -0
  38. package/dist/billing-Bv2V7KWF.d.ts +23 -0
  39. package/dist/chunk-5YXI4Q2K.js +13813 -0
  40. package/dist/chunk-75ZPJI57.cjs +9 -0
  41. package/dist/chunk-BW4BLEIM.cjs +18 -0
  42. package/dist/chunk-DZDDLA4G.js +271 -0
  43. package/dist/chunk-E5YC2MHX.cjs +13816 -0
  44. package/dist/chunk-JUTTFY3W.js +16 -0
  45. package/dist/chunk-M26EDKMY.cjs +280 -0
  46. package/dist/chunk-M3DPIKWT.js +23 -0
  47. package/dist/chunk-MLKGABMK.js +7 -0
  48. package/dist/chunk-PHTUPKEM.cjs +26 -0
  49. package/dist/cli/commands/init.cjs +11 -0
  50. package/dist/cli/commands/init.d.cts +3 -0
  51. package/dist/cli/commands/init.d.ts +3 -0
  52. package/dist/cli/commands/init.js +2 -0
  53. package/dist/cli/index.cjs +11 -0
  54. package/dist/cli/index.d.cts +1 -0
  55. package/dist/cli/index.d.ts +1 -0
  56. package/dist/cli/index.js +9 -0
  57. package/dist/email/index.cjs +526 -0
  58. package/dist/email/index.d.cts +6 -0
  59. package/dist/email/index.d.ts +6 -0
  60. package/dist/email/index.js +523 -0
  61. package/dist/email-DZN1-bHa.d.cts +19 -0
  62. package/dist/email-DZN1-bHa.d.ts +19 -0
  63. package/dist/index.cjs +27 -0
  64. package/dist/index.d.cts +23 -0
  65. package/dist/index.d.ts +23 -0
  66. package/dist/index.js +21 -0
  67. package/dist/mobile/index.cjs +101 -0
  68. package/dist/mobile/index.d.cts +15 -0
  69. package/dist/mobile/index.d.ts +15 -0
  70. package/dist/mobile/index.js +96 -0
  71. package/dist/pwa/index.cjs +80 -0
  72. package/dist/pwa/index.d.cts +51 -0
  73. package/dist/pwa/index.d.ts +51 -0
  74. package/dist/pwa/index.js +76 -0
  75. package/package.json +140 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MirageDev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,393 @@
1
+ # MirageDev SDK
2
+
3
+ AI-first SDK for building SAAS applications with Next.js. Build production-ready SAAS apps in minutes, not weeks.
4
+
5
+ [![npm version](https://badge.fury.io/js/miragedev-sdk.svg)](https://www.npmjs.com/package/miragedev-sdk)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - 🔐 **Authentication** - NextAuth.js, Clerk, Supabase support with biometric auth
11
+ - 💳 **Billing** - Stripe integration with mobile-optimized checkout
12
+ - 📧 **Email** - Beautiful React Email templates with Resend/SendGrid
13
+ - 📱 **PWA** - Progressive Web App with offline support
14
+ - 🎯 **Mobile-First** - Optimized hooks for mobile experiences
15
+ - 🤖 **AI-Friendly** - Comprehensive JSDoc for AI code generation
16
+ - 📦 **Modular** - Import only what you need
17
+ - 🔒 **Type-Safe** - Full TypeScript support with Zod validation
18
+
19
+ ## Quick Start (5 minutes)
20
+
21
+ ### 1. Installation
22
+
23
+ ```bash
24
+ npm install miragedev-sdk
25
+ # or
26
+ pnpm add miragedev-sdk
27
+ ```
28
+
29
+ ### 2. Initialize with CLI
30
+
31
+ ```bash
32
+ npx miragedev init
33
+ ```
34
+
35
+ The CLI will guide you through selecting providers and generating configuration files.
36
+
37
+ **What gets created:**
38
+ - `miragedev.config.ts` - SDK configuration
39
+ - `.env.local.example` - Environment variables template
40
+ - `miragedev.init.ts` - Initialization file
41
+ - `AGENTS.md` - Instructions for AI assistants (Copilot, Cursor, etc.)
42
+
43
+ ### 3. Configure Environment
44
+
45
+ Create `.env.local`:
46
+
47
+ ```env
48
+ # Auth
49
+ AUTH_SECRET=your-secret-key-here
50
+
51
+ # Billing (Stripe)
52
+ STRIPE_SECRET_KEY=sk_test_xxx
53
+ STRIPE_WEBHOOK_SECRET=whsec_xxx
54
+
55
+ # Email (Resend)
56
+ RESEND_API_KEY=re_xxx
57
+ EMAIL_FROM=noreply@yourapp.com
58
+ ```
59
+
60
+ ### 4. Initialize SDK
61
+
62
+ Create `lib/miragedev.ts`:
63
+
64
+ ```typescript
65
+ import { initMirageDev } from 'miragedev-sdk'
66
+
67
+ initMirageDev({
68
+ auth: {
69
+ provider: 'nextauth',
70
+ sessionSecret: process.env.AUTH_SECRET!,
71
+ },
72
+ billing: {
73
+ provider: 'stripe',
74
+ stripeSecretKey: process.env.STRIPE_SECRET_KEY!,
75
+ webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
76
+ },
77
+ email: {
78
+ provider: 'resend',
79
+ apiKey: process.env.RESEND_API_KEY!,
80
+ from: process.env.EMAIL_FROM!,
81
+ },
82
+ })
83
+ ```
84
+
85
+ Import this in your root layout (`app/layout.tsx`).
86
+
87
+ ### 5. Start Building
88
+
89
+ ```typescript
90
+ // Server Component - Protected Page
91
+ import { requireAuth } from 'miragedev-sdk/auth'
92
+
93
+ export default async function DashboardPage() {
94
+ const session = await requireAuth() // Throws if not authenticated
95
+ return <div>Welcome {session.user.name}!</div>
96
+ }
97
+ ```
98
+
99
+ ```typescript
100
+ // Client Component - Subscription Button
101
+ 'use client'
102
+ import { useSubscription } from 'miragedev-sdk/billing/client'
103
+
104
+ export function UpgradeButton() {
105
+ const { subscription, isLoading } = useSubscription()
106
+
107
+ if (subscription?.status === 'active') {
108
+ return <button>Manage Subscription</button>
109
+ }
110
+
111
+ return <button>Upgrade to Pro</button>
112
+ }
113
+ ```
114
+
115
+ ## Configuration
116
+
117
+ ### Auth Module
118
+
119
+ ```typescript
120
+ import { requireAuth, getSession } from 'miragedev-sdk/auth'
121
+ import { authMiddleware } from 'miragedev-sdk/auth/middleware'
122
+ import { useSession, signIn, signOut } from 'miragedev-sdk/auth/client'
123
+ import { enableBiometric, signInWithBiometric } from 'miragedev-sdk/auth/biometric'
124
+ ```
125
+
126
+ **Server-Side:**
127
+ - `requireAuth()` - Require authentication, throws error if not authenticated
128
+ - `getSession()` - Get current session or null
129
+
130
+ **Client-Side:**
131
+ - `useSession()` - React hook for session state
132
+ - `signIn(provider?)` - Sign in with optional provider
133
+ - `signOut()` - Sign out current user
134
+
135
+ **Middleware:**
136
+ ```typescript
137
+ // middleware.ts
138
+ export default authMiddleware({
139
+ publicRoutes: ['/', '/pricing'],
140
+ redirectTo: '/login'
141
+ })
142
+ ```
143
+
144
+ **Biometric:**
145
+ ```typescript
146
+ await enableBiometric() // Enable for current user
147
+ const session = await signInWithBiometric() // Sign in with biometric
148
+ ```
149
+
150
+ ### Billing Module
151
+
152
+ ```typescript
153
+ import {
154
+ createCheckout,
155
+ createPortal,
156
+ getSubscription,
157
+ cancelSubscription
158
+ } from 'miragedev-sdk/billing'
159
+ import { useSubscription, openBillingPortal } from 'miragedev-sdk/billing/client'
160
+ import { createMobileCheckout, createPaymentIntent } from 'miragedev-sdk/billing/mobile'
161
+ import { handleWebhook } from 'miragedev-sdk/billing/webhook'
162
+ ```
163
+
164
+ **Checkout:**
165
+ ```typescript
166
+ const { url } = await createCheckout({
167
+ priceId: 'price_xxx',
168
+ userId: session.user.id,
169
+ successUrl: 'https://yourapp.com/success',
170
+ cancelUrl: 'https://yourapp.com/cancel',
171
+ })
172
+ redirect(url)
173
+ ```
174
+
175
+ **Webhooks:**
176
+ ```typescript
177
+ // app/api/webhooks/stripe/route.ts
178
+ export async function POST(req: Request) {
179
+ return handleWebhook(req, {
180
+ onSubscriptionCreated: async (data) => {
181
+ await db.user.update({
182
+ where: { id: data.userId },
183
+ data: { isPro: true }
184
+ })
185
+ },
186
+ onSubscriptionCanceled: async (data) => {
187
+ // Handle cancellation
188
+ }
189
+ })
190
+ }
191
+ ```
192
+
193
+ **Mobile:**
194
+ ```typescript
195
+ // For mobile PWA checkout
196
+ const { clientSecret } = await createMobileCheckout({
197
+ priceId: 'price_xxx',
198
+ userId: user.id,
199
+ successUrl: 'myapp://success',
200
+ cancelUrl: 'myapp://cancel',
201
+ })
202
+ ```
203
+
204
+ ### Email Module
205
+
206
+ ```typescript
207
+ import { sendEmail, sendTemplateEmail } from 'miragedev-sdk/email'
208
+ ```
209
+
210
+ **Basic Email:**
211
+ ```typescript
212
+ await sendEmail({
213
+ to: 'user@example.com',
214
+ subject: 'Welcome!',
215
+ html: '<p>Hello World</p>',
216
+ })
217
+ ```
218
+
219
+ **Template Email:**
220
+ ```typescript
221
+ await sendTemplateEmail({
222
+ to: 'user@example.com',
223
+ template: 'welcome',
224
+ data: {
225
+ userName: 'John',
226
+ actionUrl: 'https://app.com/onboarding'
227
+ }
228
+ })
229
+ ```
230
+
231
+ **Available Templates:**
232
+ - `welcome` - Welcome new users
233
+ - `reset-password` - Password reset
234
+ - `subscription-created` - Subscription confirmation
235
+ - `subscription-canceled` - Cancellation notice
236
+ - `invoice` - Invoice notification
237
+
238
+ ### PWA Module
239
+
240
+ ```typescript
241
+ import { configurePWA } from 'miragedev-sdk/pwa'
242
+ ```
243
+
244
+ ```typescript
245
+ export const pwaConfig = configurePWA({
246
+ name: 'My SaaS App',
247
+ shortName: 'MySaaS',
248
+ theme: '#000000',
249
+ backgroundColor: '#ffffff',
250
+ offline: {
251
+ enabled: true,
252
+ pages: ['/', '/dashboard']
253
+ }
254
+ })
255
+
256
+ // Use pwaConfig.manifest in Next.js metadata
257
+ // Write pwaConfig.serviceWorker to public/sw.js
258
+ ```
259
+
260
+ ### Mobile Module
261
+
262
+ ```typescript
263
+ import {
264
+ useNetworkStatus,
265
+ useInstallPrompt,
266
+ useNotifications,
267
+ usePullToRefresh
268
+ } from 'miragedev-sdk/mobile'
269
+ ```
270
+
271
+ ```typescript
272
+ function MyComponent() {
273
+ const isOnline = useNetworkStatus()
274
+ const { canInstall, promptInstall } = useInstallPrompt()
275
+ const { permission, requestPermission } = useNotifications()
276
+ const { isRefreshing } = usePullToRefresh(async () => {
277
+ await fetchData()
278
+ })
279
+
280
+ // Your component logic
281
+ }
282
+ ```
283
+
284
+ ## API Reference
285
+
286
+ Full API documentation with examples for every function is available in the code via JSDoc. Your AI assistant can read these to help you build faster.
287
+
288
+ ## Examples
289
+
290
+ Check out the `examples/` directory for complete working applications:
291
+
292
+ - `examples/basic-saas` - Minimal SAAS with auth + billing
293
+ - `examples/with-biometric` - Biometric authentication example
294
+ - `examples/stripe-advanced` - Advanced billing with multiple tiers
295
+
296
+ ## Troubleshooting
297
+
298
+ ### "SDK not initialized" error
299
+
300
+ Make sure you call `initMirageDev()` before using any SDK functions. Import the initialization in your root layout.
301
+
302
+ ### Webhooks not working
303
+
304
+ 1. Verify your webhook secret is correct in `.env.local`
305
+ 2. Make sure your webhook endpoint is publicly accessible
306
+ 3. Check Stripe dashboard for webhook delivery logs
307
+
308
+ ### TypeScript errors
309
+
310
+ The SDK is fully typed. If you see type errors, make sure you're using TypeScript 5.0+ and have `strict: true` in your tsconfig.json.
311
+
312
+ ## Publishing the SDK
313
+
314
+ ### For Maintainers: Automated Publishing
315
+
316
+ This SDK uses **automated versioning and publishing** via GitHub Actions.
317
+
318
+ #### How It Works
319
+
320
+ When a PR is merged to `main`:
321
+ 1. ✅ Tests run automatically
322
+ 2. ✅ Version is bumped based on commit messages:
323
+ - `feat:` → minor version (0.1.0 → 0.2.0)
324
+ - `fix:` → patch version (0.1.0 → 0.1.1)
325
+ - `feat!:` or `BREAKING CHANGE` → major version (0.1.0 → 1.0.0)
326
+ 3. ✅ package.json is updated and committed
327
+ 4. ✅ Git tag is created automatically
328
+ 5. ✅ Package is published to NPM
329
+ 6. ✅ GitHub Release is created
330
+
331
+ #### Setup (One Time)
332
+
333
+ 1. Add `NPM_TOKEN` to GitHub repository secrets:
334
+ - Go to npmjs.com → Access Tokens → Generate New Token (Automation)
335
+ - Copy token
336
+ - Go to GitHub repo → Settings → Secrets → New secret
337
+ - Name: `NPM_TOKEN`, Value: (paste token)
338
+
339
+ 2. That's it! Now every merge to main auto-publishes.
340
+
341
+ #### Publishing Process
342
+
343
+ **Simple workflow:**
344
+ ```bash
345
+ # 1. Create feature branch
346
+ git checkout -b feat/new-feature
347
+
348
+ # 2. Make changes with conventional commits
349
+ git commit -m "feat: add new awesome feature"
350
+
351
+ # 3. Push and create PR
352
+ git push origin feat/new-feature
353
+
354
+ # 4. Merge PR to main
355
+ # → GitHub Actions automatically:
356
+ # - Runs tests
357
+ # - Bumps version (0.1.0 → 0.2.0)
358
+ # - Publishes to NPM
359
+ # - Creates release
360
+ ```
361
+
362
+ **No manual `npm version` or `npm publish` needed!**
363
+
364
+ #### Manual Publishing (Emergency Only)
365
+
366
+ If you need to publish manually:
367
+ ```bash
368
+ npm version patch # or minor/major
369
+ npm run prepublishOnly # Runs type-check, tests, build
370
+ npm publish --access public
371
+ git push && git push --tags
372
+ ```
373
+
374
+ #### After Publishing
375
+
376
+ Users can install the latest version:
377
+ ```bash
378
+ npm install miragedev-sdk@latest
379
+ ```
380
+
381
+ ## License
382
+
383
+ MIT © MirageDev
384
+
385
+ ## Support
386
+
387
+ - 📖 [Documentation](https://github.com/miragedev/miragedev-sdk)
388
+ - 🐛 [Issue Tracker](https://github.com/miragedev/miragedev-sdk/issues)
389
+ - 💬 [Discussions](https://github.com/miragedev/miragedev-sdk/discussions)
390
+
391
+ ---
392
+
393
+ Built with ❤️ for the Next.js community
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ var chunkBW4BLEIM_cjs = require('../chunk-BW4BLEIM.cjs');
4
+ require('../chunk-75ZPJI57.cjs');
5
+
6
+ // src/auth/biometric.ts
7
+ function isBiometricSupported() {
8
+ return typeof window !== "undefined" && window.PublicKeyCredential !== void 0 && typeof window.PublicKeyCredential === "function";
9
+ }
10
+ async function enableBiometric() {
11
+ if (!isBiometricSupported()) {
12
+ throw new chunkBW4BLEIM_cjs.MirageDevError(
13
+ "AUTH_INVALID_CREDENTIALS",
14
+ "Biometric authentication is not supported in this browser"
15
+ );
16
+ }
17
+ try {
18
+ const optionsResponse = await fetch("/api/auth/biometric/register", {
19
+ method: "POST"
20
+ });
21
+ if (!optionsResponse.ok) {
22
+ throw new Error("Failed to get registration options");
23
+ }
24
+ const options = await optionsResponse.json();
25
+ const credential = await navigator.credentials.create({
26
+ publicKey: options
27
+ });
28
+ if (!credential) {
29
+ throw new Error("Failed to create credentials");
30
+ }
31
+ const registerResponse = await fetch("/api/auth/biometric/verify", {
32
+ method: "POST",
33
+ headers: { "Content-Type": "application/json" },
34
+ body: JSON.stringify(credential)
35
+ });
36
+ if (!registerResponse.ok) {
37
+ throw new Error("Failed to register biometric");
38
+ }
39
+ } catch (error) {
40
+ throw new chunkBW4BLEIM_cjs.MirageDevError(
41
+ "AUTH_INVALID_CREDENTIALS",
42
+ `Failed to enable biometric authentication: ${error.message}`
43
+ );
44
+ }
45
+ }
46
+ async function signInWithBiometric() {
47
+ if (!isBiometricSupported()) {
48
+ throw new chunkBW4BLEIM_cjs.MirageDevError(
49
+ "AUTH_INVALID_CREDENTIALS",
50
+ "Biometric authentication is not supported in this browser"
51
+ );
52
+ }
53
+ try {
54
+ const optionsResponse = await fetch("/api/auth/biometric/authenticate");
55
+ if (!optionsResponse.ok) {
56
+ throw new Error("Failed to get authentication options");
57
+ }
58
+ const options = await optionsResponse.json();
59
+ const credential = await navigator.credentials.get({
60
+ publicKey: options
61
+ });
62
+ if (!credential) {
63
+ throw new Error("Failed to get credentials");
64
+ }
65
+ const verifyResponse = await fetch("/api/auth/biometric/verify", {
66
+ method: "POST",
67
+ headers: { "Content-Type": "application/json" },
68
+ body: JSON.stringify(credential)
69
+ });
70
+ if (!verifyResponse.ok) {
71
+ throw new Error("Failed to verify biometric");
72
+ }
73
+ const session = await verifyResponse.json();
74
+ return session;
75
+ } catch (error) {
76
+ throw new chunkBW4BLEIM_cjs.MirageDevError(
77
+ "AUTH_INVALID_CREDENTIALS",
78
+ `Biometric authentication failed: ${error.message}`
79
+ );
80
+ }
81
+ }
82
+
83
+ exports.enableBiometric = enableBiometric;
84
+ exports.isBiometricSupported = isBiometricSupported;
85
+ exports.signInWithBiometric = signInWithBiometric;
@@ -0,0 +1,7 @@
1
+ import { S as Session } from '../auth-BC8JI28z.cjs';
2
+
3
+ declare function isBiometricSupported(): boolean;
4
+ declare function enableBiometric(): Promise<void>;
5
+ declare function signInWithBiometric(): Promise<Session>;
6
+
7
+ export { enableBiometric, isBiometricSupported, signInWithBiometric };
@@ -0,0 +1,7 @@
1
+ import { S as Session } from '../auth-BC8JI28z.js';
2
+
3
+ declare function isBiometricSupported(): boolean;
4
+ declare function enableBiometric(): Promise<void>;
5
+ declare function signInWithBiometric(): Promise<Session>;
6
+
7
+ export { enableBiometric, isBiometricSupported, signInWithBiometric };
@@ -0,0 +1,81 @@
1
+ import { MirageDevError } from '../chunk-JUTTFY3W.js';
2
+ import '../chunk-MLKGABMK.js';
3
+
4
+ // src/auth/biometric.ts
5
+ function isBiometricSupported() {
6
+ return typeof window !== "undefined" && window.PublicKeyCredential !== void 0 && typeof window.PublicKeyCredential === "function";
7
+ }
8
+ async function enableBiometric() {
9
+ if (!isBiometricSupported()) {
10
+ throw new MirageDevError(
11
+ "AUTH_INVALID_CREDENTIALS",
12
+ "Biometric authentication is not supported in this browser"
13
+ );
14
+ }
15
+ try {
16
+ const optionsResponse = await fetch("/api/auth/biometric/register", {
17
+ method: "POST"
18
+ });
19
+ if (!optionsResponse.ok) {
20
+ throw new Error("Failed to get registration options");
21
+ }
22
+ const options = await optionsResponse.json();
23
+ const credential = await navigator.credentials.create({
24
+ publicKey: options
25
+ });
26
+ if (!credential) {
27
+ throw new Error("Failed to create credentials");
28
+ }
29
+ const registerResponse = await fetch("/api/auth/biometric/verify", {
30
+ method: "POST",
31
+ headers: { "Content-Type": "application/json" },
32
+ body: JSON.stringify(credential)
33
+ });
34
+ if (!registerResponse.ok) {
35
+ throw new Error("Failed to register biometric");
36
+ }
37
+ } catch (error) {
38
+ throw new MirageDevError(
39
+ "AUTH_INVALID_CREDENTIALS",
40
+ `Failed to enable biometric authentication: ${error.message}`
41
+ );
42
+ }
43
+ }
44
+ async function signInWithBiometric() {
45
+ if (!isBiometricSupported()) {
46
+ throw new MirageDevError(
47
+ "AUTH_INVALID_CREDENTIALS",
48
+ "Biometric authentication is not supported in this browser"
49
+ );
50
+ }
51
+ try {
52
+ const optionsResponse = await fetch("/api/auth/biometric/authenticate");
53
+ if (!optionsResponse.ok) {
54
+ throw new Error("Failed to get authentication options");
55
+ }
56
+ const options = await optionsResponse.json();
57
+ const credential = await navigator.credentials.get({
58
+ publicKey: options
59
+ });
60
+ if (!credential) {
61
+ throw new Error("Failed to get credentials");
62
+ }
63
+ const verifyResponse = await fetch("/api/auth/biometric/verify", {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify(credential)
67
+ });
68
+ if (!verifyResponse.ok) {
69
+ throw new Error("Failed to verify biometric");
70
+ }
71
+ const session = await verifyResponse.json();
72
+ return session;
73
+ } catch (error) {
74
+ throw new MirageDevError(
75
+ "AUTH_INVALID_CREDENTIALS",
76
+ `Biometric authentication failed: ${error.message}`
77
+ );
78
+ }
79
+ }
80
+
81
+ export { enableBiometric, isBiometricSupported, signInWithBiometric };
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ require('../chunk-75ZPJI57.cjs');
4
+ var react = require('react');
5
+
6
+ function useSession() {
7
+ const [session, setSession] = react.useState(null);
8
+ const [status, setStatus] = react.useState("loading");
9
+ react.useEffect(() => {
10
+ fetch("/api/auth/session").then((res) => res.json()).then((data) => {
11
+ if (data && data.user) {
12
+ setSession(data);
13
+ setStatus("authenticated");
14
+ } else {
15
+ setSession(null);
16
+ setStatus("unauthenticated");
17
+ }
18
+ }).catch(() => {
19
+ setSession(null);
20
+ setStatus("unauthenticated");
21
+ });
22
+ }, []);
23
+ return { session, status };
24
+ }
25
+ async function signIn(provider) {
26
+ const url = provider ? `/api/auth/signin/${provider}` : "/api/auth/signin";
27
+ if (typeof window !== "undefined") {
28
+ window.location.href = url;
29
+ }
30
+ }
31
+ async function signOut() {
32
+ try {
33
+ await fetch("/api/auth/signout", { method: "POST" });
34
+ if (typeof window !== "undefined") {
35
+ window.location.href = "/";
36
+ }
37
+ } catch (error) {
38
+ console.error("Sign out failed:", error);
39
+ }
40
+ }
41
+
42
+ exports.signIn = signIn;
43
+ exports.signOut = signOut;
44
+ exports.useSession = useSession;
@@ -0,0 +1,12 @@
1
+ import { S as Session } from '../auth-BC8JI28z.cjs';
2
+
3
+ type SessionStatus = 'authenticated' | 'unauthenticated' | 'loading';
4
+ interface UseSessionReturn {
5
+ session: Session | null;
6
+ status: SessionStatus;
7
+ }
8
+ declare function useSession(): UseSessionReturn;
9
+ declare function signIn(provider?: string): Promise<void>;
10
+ declare function signOut(): Promise<void>;
11
+
12
+ export { type SessionStatus, type UseSessionReturn, signIn, signOut, useSession };
@@ -0,0 +1,12 @@
1
+ import { S as Session } from '../auth-BC8JI28z.js';
2
+
3
+ type SessionStatus = 'authenticated' | 'unauthenticated' | 'loading';
4
+ interface UseSessionReturn {
5
+ session: Session | null;
6
+ status: SessionStatus;
7
+ }
8
+ declare function useSession(): UseSessionReturn;
9
+ declare function signIn(provider?: string): Promise<void>;
10
+ declare function signOut(): Promise<void>;
11
+
12
+ export { type SessionStatus, type UseSessionReturn, signIn, signOut, useSession };