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.
- package/LICENSE +21 -0
- package/README.md +393 -0
- package/dist/auth/biometric.cjs +85 -0
- package/dist/auth/biometric.d.cts +7 -0
- package/dist/auth/biometric.d.ts +7 -0
- package/dist/auth/biometric.js +81 -0
- package/dist/auth/client.cjs +44 -0
- package/dist/auth/client.d.cts +12 -0
- package/dist/auth/client.d.ts +12 -0
- package/dist/auth/client.js +40 -0
- package/dist/auth/index.cjs +17 -0
- package/dist/auth/index.d.cts +6 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +4 -0
- package/dist/auth/middleware.cjs +37 -0
- package/dist/auth/middleware.d.cts +10 -0
- package/dist/auth/middleware.d.ts +10 -0
- package/dist/auth/middleware.js +35 -0
- package/dist/auth-BC8JI28z.d.cts +22 -0
- package/dist/auth-BC8JI28z.d.ts +22 -0
- package/dist/billing/client.cjs +43 -0
- package/dist/billing/client.d.cts +11 -0
- package/dist/billing/client.d.ts +11 -0
- package/dist/billing/client.js +40 -0
- package/dist/billing/index.cjs +139 -0
- package/dist/billing/index.d.cts +12 -0
- package/dist/billing/index.d.ts +12 -0
- package/dist/billing/index.js +130 -0
- package/dist/billing/mobile.cjs +81 -0
- package/dist/billing/mobile.d.cts +17 -0
- package/dist/billing/mobile.d.ts +17 -0
- package/dist/billing/mobile.js +74 -0
- package/dist/billing/webhook.cjs +84 -0
- package/dist/billing/webhook.d.cts +19 -0
- package/dist/billing/webhook.d.ts +19 -0
- package/dist/billing/webhook.js +78 -0
- package/dist/billing-Bv2V7KWF.d.cts +23 -0
- package/dist/billing-Bv2V7KWF.d.ts +23 -0
- package/dist/chunk-5YXI4Q2K.js +13813 -0
- package/dist/chunk-75ZPJI57.cjs +9 -0
- package/dist/chunk-BW4BLEIM.cjs +18 -0
- package/dist/chunk-DZDDLA4G.js +271 -0
- package/dist/chunk-E5YC2MHX.cjs +13816 -0
- package/dist/chunk-JUTTFY3W.js +16 -0
- package/dist/chunk-M26EDKMY.cjs +280 -0
- package/dist/chunk-M3DPIKWT.js +23 -0
- package/dist/chunk-MLKGABMK.js +7 -0
- package/dist/chunk-PHTUPKEM.cjs +26 -0
- package/dist/cli/commands/init.cjs +11 -0
- package/dist/cli/commands/init.d.cts +3 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.js +2 -0
- package/dist/cli/index.cjs +11 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +9 -0
- package/dist/email/index.cjs +526 -0
- package/dist/email/index.d.cts +6 -0
- package/dist/email/index.d.ts +6 -0
- package/dist/email/index.js +523 -0
- package/dist/email-DZN1-bHa.d.cts +19 -0
- package/dist/email-DZN1-bHa.d.ts +19 -0
- package/dist/index.cjs +27 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +21 -0
- package/dist/mobile/index.cjs +101 -0
- package/dist/mobile/index.d.cts +15 -0
- package/dist/mobile/index.d.ts +15 -0
- package/dist/mobile/index.js +96 -0
- package/dist/pwa/index.cjs +80 -0
- package/dist/pwa/index.d.cts +51 -0
- package/dist/pwa/index.d.ts +51 -0
- package/dist/pwa/index.js +76 -0
- package/package.json +140 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import '../chunk-MLKGABMK.js';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
function useSession() {
|
|
5
|
+
const [session, setSession] = useState(null);
|
|
6
|
+
const [status, setStatus] = useState("loading");
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
fetch("/api/auth/session").then((res) => res.json()).then((data) => {
|
|
9
|
+
if (data && data.user) {
|
|
10
|
+
setSession(data);
|
|
11
|
+
setStatus("authenticated");
|
|
12
|
+
} else {
|
|
13
|
+
setSession(null);
|
|
14
|
+
setStatus("unauthenticated");
|
|
15
|
+
}
|
|
16
|
+
}).catch(() => {
|
|
17
|
+
setSession(null);
|
|
18
|
+
setStatus("unauthenticated");
|
|
19
|
+
});
|
|
20
|
+
}, []);
|
|
21
|
+
return { session, status };
|
|
22
|
+
}
|
|
23
|
+
async function signIn(provider) {
|
|
24
|
+
const url = provider ? `/api/auth/signin/${provider}` : "/api/auth/signin";
|
|
25
|
+
if (typeof window !== "undefined") {
|
|
26
|
+
window.location.href = url;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function signOut() {
|
|
30
|
+
try {
|
|
31
|
+
await fetch("/api/auth/signout", { method: "POST" });
|
|
32
|
+
if (typeof window !== "undefined") {
|
|
33
|
+
window.location.href = "/";
|
|
34
|
+
}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error("Sign out failed:", error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { signIn, signOut, useSession };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkPHTUPKEM_cjs = require('../chunk-PHTUPKEM.cjs');
|
|
4
|
+
require('../chunk-E5YC2MHX.cjs');
|
|
5
|
+
require('../chunk-BW4BLEIM.cjs');
|
|
6
|
+
require('../chunk-75ZPJI57.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Object.defineProperty(exports, "getSession", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () { return chunkPHTUPKEM_cjs.getSession; }
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "requireAuth", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return chunkPHTUPKEM_cjs.requireAuth; }
|
|
17
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkPHTUPKEM_cjs = require('../chunk-PHTUPKEM.cjs');
|
|
4
|
+
require('../chunk-E5YC2MHX.cjs');
|
|
5
|
+
require('../chunk-BW4BLEIM.cjs');
|
|
6
|
+
require('../chunk-75ZPJI57.cjs');
|
|
7
|
+
|
|
8
|
+
// src/auth/middleware.ts
|
|
9
|
+
function authMiddleware(options = {}) {
|
|
10
|
+
const {
|
|
11
|
+
publicRoutes = [],
|
|
12
|
+
redirectTo = "/login"
|
|
13
|
+
} = options;
|
|
14
|
+
return async function middleware(request) {
|
|
15
|
+
const pathname = request.nextUrl?.pathname || request.url;
|
|
16
|
+
const isPublicRoute = publicRoutes.some((route) => {
|
|
17
|
+
if (route === pathname) return true;
|
|
18
|
+
if (route.endsWith("*")) {
|
|
19
|
+
const baseRoute = route.slice(0, -1);
|
|
20
|
+
return pathname.startsWith(baseRoute);
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
});
|
|
24
|
+
if (isPublicRoute) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const session = await chunkPHTUPKEM_cjs.getSession();
|
|
28
|
+
if (!session) {
|
|
29
|
+
return {
|
|
30
|
+
redirect: redirectTo
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
exports.authMiddleware = authMiddleware;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface MiddlewareOptions {
|
|
2
|
+
publicRoutes?: string[];
|
|
3
|
+
redirectTo?: string;
|
|
4
|
+
matcher?: string[];
|
|
5
|
+
}
|
|
6
|
+
declare function authMiddleware(options?: MiddlewareOptions): (request: any) => Promise<{
|
|
7
|
+
redirect: string;
|
|
8
|
+
} | null>;
|
|
9
|
+
|
|
10
|
+
export { type MiddlewareOptions, authMiddleware };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface MiddlewareOptions {
|
|
2
|
+
publicRoutes?: string[];
|
|
3
|
+
redirectTo?: string;
|
|
4
|
+
matcher?: string[];
|
|
5
|
+
}
|
|
6
|
+
declare function authMiddleware(options?: MiddlewareOptions): (request: any) => Promise<{
|
|
7
|
+
redirect: string;
|
|
8
|
+
} | null>;
|
|
9
|
+
|
|
10
|
+
export { type MiddlewareOptions, authMiddleware };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getSession } from '../chunk-M3DPIKWT.js';
|
|
2
|
+
import '../chunk-5YXI4Q2K.js';
|
|
3
|
+
import '../chunk-JUTTFY3W.js';
|
|
4
|
+
import '../chunk-MLKGABMK.js';
|
|
5
|
+
|
|
6
|
+
// src/auth/middleware.ts
|
|
7
|
+
function authMiddleware(options = {}) {
|
|
8
|
+
const {
|
|
9
|
+
publicRoutes = [],
|
|
10
|
+
redirectTo = "/login"
|
|
11
|
+
} = options;
|
|
12
|
+
return async function middleware(request) {
|
|
13
|
+
const pathname = request.nextUrl?.pathname || request.url;
|
|
14
|
+
const isPublicRoute = publicRoutes.some((route) => {
|
|
15
|
+
if (route === pathname) return true;
|
|
16
|
+
if (route.endsWith("*")) {
|
|
17
|
+
const baseRoute = route.slice(0, -1);
|
|
18
|
+
return pathname.startsWith(baseRoute);
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
});
|
|
22
|
+
if (isPublicRoute) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const session = await getSession();
|
|
26
|
+
if (!session) {
|
|
27
|
+
return {
|
|
28
|
+
redirect: redirectTo
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { authMiddleware };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type User = {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name: string | null;
|
|
5
|
+
image?: string;
|
|
6
|
+
};
|
|
7
|
+
type Session = {
|
|
8
|
+
user: User;
|
|
9
|
+
expiresAt: Date;
|
|
10
|
+
};
|
|
11
|
+
type AuthProvider = 'nextauth' | 'clerk' | 'supabase' | 'custom';
|
|
12
|
+
type SessionStrategy = 'jwt' | 'database';
|
|
13
|
+
type AuthConfig = {
|
|
14
|
+
provider: AuthProvider;
|
|
15
|
+
sessionSecret: string;
|
|
16
|
+
session?: {
|
|
17
|
+
strategy?: SessionStrategy;
|
|
18
|
+
maxAge?: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type { AuthConfig as A, Session as S, User as U, AuthProvider as a, SessionStrategy as b };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type User = {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name: string | null;
|
|
5
|
+
image?: string;
|
|
6
|
+
};
|
|
7
|
+
type Session = {
|
|
8
|
+
user: User;
|
|
9
|
+
expiresAt: Date;
|
|
10
|
+
};
|
|
11
|
+
type AuthProvider = 'nextauth' | 'clerk' | 'supabase' | 'custom';
|
|
12
|
+
type SessionStrategy = 'jwt' | 'database';
|
|
13
|
+
type AuthConfig = {
|
|
14
|
+
provider: AuthProvider;
|
|
15
|
+
sessionSecret: string;
|
|
16
|
+
session?: {
|
|
17
|
+
strategy?: SessionStrategy;
|
|
18
|
+
maxAge?: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type { AuthConfig as A, Session as S, User as U, AuthProvider as a, SessionStrategy as b };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('../chunk-75ZPJI57.cjs');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
function useSubscription() {
|
|
7
|
+
const [subscription, setSubscription] = react.useState(null);
|
|
8
|
+
const [isLoading, setIsLoading] = react.useState(true);
|
|
9
|
+
const [error, setError] = react.useState(null);
|
|
10
|
+
react.useEffect(() => {
|
|
11
|
+
fetch("/api/subscription").then((res) => res.json()).then((data) => {
|
|
12
|
+
if (data && data.id) {
|
|
13
|
+
if (data.currentPeriodEnd) {
|
|
14
|
+
data.currentPeriodEnd = new Date(data.currentPeriodEnd);
|
|
15
|
+
}
|
|
16
|
+
setSubscription(data);
|
|
17
|
+
} else {
|
|
18
|
+
setSubscription(null);
|
|
19
|
+
}
|
|
20
|
+
setIsLoading(false);
|
|
21
|
+
}).catch((err) => {
|
|
22
|
+
setError(err);
|
|
23
|
+
setIsLoading(false);
|
|
24
|
+
});
|
|
25
|
+
}, []);
|
|
26
|
+
return { subscription, isLoading, error };
|
|
27
|
+
}
|
|
28
|
+
async function openBillingPortal() {
|
|
29
|
+
try {
|
|
30
|
+
const response = await fetch("/api/billing/portal", {
|
|
31
|
+
method: "POST"
|
|
32
|
+
});
|
|
33
|
+
const data = await response.json();
|
|
34
|
+
if (data.url && typeof window !== "undefined") {
|
|
35
|
+
window.location.href = data.url;
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("Failed to open billing portal:", error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
exports.openBillingPortal = openBillingPortal;
|
|
43
|
+
exports.useSubscription = useSubscription;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { S as Subscription } from '../billing-Bv2V7KWF.cjs';
|
|
2
|
+
|
|
3
|
+
interface UseSubscriptionReturn {
|
|
4
|
+
subscription: Subscription | null;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
}
|
|
8
|
+
declare function useSubscription(): UseSubscriptionReturn;
|
|
9
|
+
declare function openBillingPortal(): Promise<void>;
|
|
10
|
+
|
|
11
|
+
export { type UseSubscriptionReturn, openBillingPortal, useSubscription };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { S as Subscription } from '../billing-Bv2V7KWF.js';
|
|
2
|
+
|
|
3
|
+
interface UseSubscriptionReturn {
|
|
4
|
+
subscription: Subscription | null;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
}
|
|
8
|
+
declare function useSubscription(): UseSubscriptionReturn;
|
|
9
|
+
declare function openBillingPortal(): Promise<void>;
|
|
10
|
+
|
|
11
|
+
export { type UseSubscriptionReturn, openBillingPortal, useSubscription };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import '../chunk-MLKGABMK.js';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
function useSubscription() {
|
|
5
|
+
const [subscription, setSubscription] = useState(null);
|
|
6
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
fetch("/api/subscription").then((res) => res.json()).then((data) => {
|
|
10
|
+
if (data && data.id) {
|
|
11
|
+
if (data.currentPeriodEnd) {
|
|
12
|
+
data.currentPeriodEnd = new Date(data.currentPeriodEnd);
|
|
13
|
+
}
|
|
14
|
+
setSubscription(data);
|
|
15
|
+
} else {
|
|
16
|
+
setSubscription(null);
|
|
17
|
+
}
|
|
18
|
+
setIsLoading(false);
|
|
19
|
+
}).catch((err) => {
|
|
20
|
+
setError(err);
|
|
21
|
+
setIsLoading(false);
|
|
22
|
+
});
|
|
23
|
+
}, []);
|
|
24
|
+
return { subscription, isLoading, error };
|
|
25
|
+
}
|
|
26
|
+
async function openBillingPortal() {
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch("/api/billing/portal", {
|
|
29
|
+
method: "POST"
|
|
30
|
+
});
|
|
31
|
+
const data = await response.json();
|
|
32
|
+
if (data.url && typeof window !== "undefined") {
|
|
33
|
+
window.location.href = data.url;
|
|
34
|
+
}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error("Failed to open billing portal:", error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { openBillingPortal, useSubscription };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkE5YC2MHX_cjs = require('../chunk-E5YC2MHX.cjs');
|
|
4
|
+
var chunkBW4BLEIM_cjs = require('../chunk-BW4BLEIM.cjs');
|
|
5
|
+
require('../chunk-75ZPJI57.cjs');
|
|
6
|
+
var Stripe = require('stripe');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var Stripe__default = /*#__PURE__*/_interopDefault(Stripe);
|
|
11
|
+
|
|
12
|
+
var StripeProvider = class {
|
|
13
|
+
stripe;
|
|
14
|
+
constructor(secretKey) {
|
|
15
|
+
this.stripe = new Stripe__default.default(secretKey, {
|
|
16
|
+
apiVersion: "2025-12-15.clover"
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Creates a Stripe checkout session
|
|
21
|
+
*/
|
|
22
|
+
async createCheckoutSession(options) {
|
|
23
|
+
try {
|
|
24
|
+
const session = await this.stripe.checkout.sessions.create({
|
|
25
|
+
mode: "subscription",
|
|
26
|
+
payment_method_types: ["card"],
|
|
27
|
+
line_items: [
|
|
28
|
+
{
|
|
29
|
+
price: options.priceId,
|
|
30
|
+
quantity: 1
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
success_url: options.successUrl,
|
|
34
|
+
cancel_url: options.cancelUrl,
|
|
35
|
+
client_reference_id: options.userId,
|
|
36
|
+
metadata: options.metadata
|
|
37
|
+
});
|
|
38
|
+
if (!session.url) {
|
|
39
|
+
throw new Error("No URL returned from Stripe");
|
|
40
|
+
}
|
|
41
|
+
return { url: session.url };
|
|
42
|
+
} catch (error) {
|
|
43
|
+
throw new chunkBW4BLEIM_cjs.MirageDevError(
|
|
44
|
+
"BILLING_STRIPE_ERROR",
|
|
45
|
+
`Failed to create checkout session: ${error.message}`,
|
|
46
|
+
error
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a Stripe billing portal session
|
|
52
|
+
*/
|
|
53
|
+
async createPortalSession(customerId, returnUrl) {
|
|
54
|
+
try {
|
|
55
|
+
const session = await this.stripe.billingPortal.sessions.create({
|
|
56
|
+
customer: customerId,
|
|
57
|
+
return_url: returnUrl
|
|
58
|
+
});
|
|
59
|
+
return { url: session.url };
|
|
60
|
+
} catch (error) {
|
|
61
|
+
throw new chunkBW4BLEIM_cjs.MirageDevError(
|
|
62
|
+
"BILLING_STRIPE_ERROR",
|
|
63
|
+
`Failed to create portal session: ${error.message}`,
|
|
64
|
+
error
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves a subscription by ID
|
|
70
|
+
*/
|
|
71
|
+
async getSubscription(subscriptionId) {
|
|
72
|
+
try {
|
|
73
|
+
const subscription = await this.stripe.subscriptions.retrieve(subscriptionId);
|
|
74
|
+
return {
|
|
75
|
+
id: subscription.id,
|
|
76
|
+
status: subscription.status,
|
|
77
|
+
plan: subscription.items.data[0]?.price.id || "",
|
|
78
|
+
currentPeriodEnd: subscription.current_period_end ? new Date(subscription.current_period_end * 1e3) : null,
|
|
79
|
+
cancelAtPeriodEnd: subscription.cancel_at_period_end || false
|
|
80
|
+
};
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error.type === "StripeInvalidRequestError") {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
throw new chunkBW4BLEIM_cjs.MirageDevError(
|
|
86
|
+
"BILLING_STRIPE_ERROR",
|
|
87
|
+
`Failed to retrieve subscription: ${error.message}`,
|
|
88
|
+
error
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Cancels a subscription
|
|
94
|
+
*/
|
|
95
|
+
async cancelSubscription(subscriptionId) {
|
|
96
|
+
try {
|
|
97
|
+
await this.stripe.subscriptions.cancel(subscriptionId);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
throw new chunkBW4BLEIM_cjs.MirageDevError(
|
|
100
|
+
"BILLING_STRIPE_ERROR",
|
|
101
|
+
`Failed to cancel subscription: ${error.message}`,
|
|
102
|
+
error
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// src/billing/index.ts
|
|
109
|
+
function getBillingProvider() {
|
|
110
|
+
const config = chunkE5YC2MHX_cjs.getConfig();
|
|
111
|
+
if (config.billing.provider === "stripe") {
|
|
112
|
+
if (!config.billing.stripeSecretKey) {
|
|
113
|
+
throw new Error("Stripe secret key is required");
|
|
114
|
+
}
|
|
115
|
+
return new StripeProvider(config.billing.stripeSecretKey);
|
|
116
|
+
}
|
|
117
|
+
throw new Error(`Unsupported billing provider: ${config.billing.provider}`);
|
|
118
|
+
}
|
|
119
|
+
async function createCheckout(options) {
|
|
120
|
+
const provider = getBillingProvider();
|
|
121
|
+
return provider.createCheckoutSession(options);
|
|
122
|
+
}
|
|
123
|
+
async function createPortal(customerId, returnUrl) {
|
|
124
|
+
const provider = getBillingProvider();
|
|
125
|
+
return provider.createPortalSession(customerId, returnUrl);
|
|
126
|
+
}
|
|
127
|
+
async function getSubscription(subscriptionId) {
|
|
128
|
+
const provider = getBillingProvider();
|
|
129
|
+
return provider.getSubscription(subscriptionId);
|
|
130
|
+
}
|
|
131
|
+
async function cancelSubscription(subscriptionId) {
|
|
132
|
+
const provider = getBillingProvider();
|
|
133
|
+
return provider.cancelSubscription(subscriptionId);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
exports.cancelSubscription = cancelSubscription;
|
|
137
|
+
exports.createCheckout = createCheckout;
|
|
138
|
+
exports.createPortal = createPortal;
|
|
139
|
+
exports.getSubscription = getSubscription;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { C as CheckoutOptions, S as Subscription } from '../billing-Bv2V7KWF.cjs';
|
|
2
|
+
|
|
3
|
+
declare function createCheckout(options: CheckoutOptions): Promise<{
|
|
4
|
+
url: string;
|
|
5
|
+
}>;
|
|
6
|
+
declare function createPortal(customerId: string, returnUrl: string): Promise<{
|
|
7
|
+
url: string;
|
|
8
|
+
}>;
|
|
9
|
+
declare function getSubscription(subscriptionId: string): Promise<Subscription | null>;
|
|
10
|
+
declare function cancelSubscription(subscriptionId: string): Promise<void>;
|
|
11
|
+
|
|
12
|
+
export { cancelSubscription, createCheckout, createPortal, getSubscription };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { C as CheckoutOptions, S as Subscription } from '../billing-Bv2V7KWF.js';
|
|
2
|
+
|
|
3
|
+
declare function createCheckout(options: CheckoutOptions): Promise<{
|
|
4
|
+
url: string;
|
|
5
|
+
}>;
|
|
6
|
+
declare function createPortal(customerId: string, returnUrl: string): Promise<{
|
|
7
|
+
url: string;
|
|
8
|
+
}>;
|
|
9
|
+
declare function getSubscription(subscriptionId: string): Promise<Subscription | null>;
|
|
10
|
+
declare function cancelSubscription(subscriptionId: string): Promise<void>;
|
|
11
|
+
|
|
12
|
+
export { cancelSubscription, createCheckout, createPortal, getSubscription };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { getConfig } from '../chunk-5YXI4Q2K.js';
|
|
2
|
+
import { MirageDevError } from '../chunk-JUTTFY3W.js';
|
|
3
|
+
import '../chunk-MLKGABMK.js';
|
|
4
|
+
import Stripe from 'stripe';
|
|
5
|
+
|
|
6
|
+
var StripeProvider = class {
|
|
7
|
+
stripe;
|
|
8
|
+
constructor(secretKey) {
|
|
9
|
+
this.stripe = new Stripe(secretKey, {
|
|
10
|
+
apiVersion: "2025-12-15.clover"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a Stripe checkout session
|
|
15
|
+
*/
|
|
16
|
+
async createCheckoutSession(options) {
|
|
17
|
+
try {
|
|
18
|
+
const session = await this.stripe.checkout.sessions.create({
|
|
19
|
+
mode: "subscription",
|
|
20
|
+
payment_method_types: ["card"],
|
|
21
|
+
line_items: [
|
|
22
|
+
{
|
|
23
|
+
price: options.priceId,
|
|
24
|
+
quantity: 1
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
success_url: options.successUrl,
|
|
28
|
+
cancel_url: options.cancelUrl,
|
|
29
|
+
client_reference_id: options.userId,
|
|
30
|
+
metadata: options.metadata
|
|
31
|
+
});
|
|
32
|
+
if (!session.url) {
|
|
33
|
+
throw new Error("No URL returned from Stripe");
|
|
34
|
+
}
|
|
35
|
+
return { url: session.url };
|
|
36
|
+
} catch (error) {
|
|
37
|
+
throw new MirageDevError(
|
|
38
|
+
"BILLING_STRIPE_ERROR",
|
|
39
|
+
`Failed to create checkout session: ${error.message}`,
|
|
40
|
+
error
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a Stripe billing portal session
|
|
46
|
+
*/
|
|
47
|
+
async createPortalSession(customerId, returnUrl) {
|
|
48
|
+
try {
|
|
49
|
+
const session = await this.stripe.billingPortal.sessions.create({
|
|
50
|
+
customer: customerId,
|
|
51
|
+
return_url: returnUrl
|
|
52
|
+
});
|
|
53
|
+
return { url: session.url };
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw new MirageDevError(
|
|
56
|
+
"BILLING_STRIPE_ERROR",
|
|
57
|
+
`Failed to create portal session: ${error.message}`,
|
|
58
|
+
error
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Retrieves a subscription by ID
|
|
64
|
+
*/
|
|
65
|
+
async getSubscription(subscriptionId) {
|
|
66
|
+
try {
|
|
67
|
+
const subscription = await this.stripe.subscriptions.retrieve(subscriptionId);
|
|
68
|
+
return {
|
|
69
|
+
id: subscription.id,
|
|
70
|
+
status: subscription.status,
|
|
71
|
+
plan: subscription.items.data[0]?.price.id || "",
|
|
72
|
+
currentPeriodEnd: subscription.current_period_end ? new Date(subscription.current_period_end * 1e3) : null,
|
|
73
|
+
cancelAtPeriodEnd: subscription.cancel_at_period_end || false
|
|
74
|
+
};
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error.type === "StripeInvalidRequestError") {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
throw new MirageDevError(
|
|
80
|
+
"BILLING_STRIPE_ERROR",
|
|
81
|
+
`Failed to retrieve subscription: ${error.message}`,
|
|
82
|
+
error
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Cancels a subscription
|
|
88
|
+
*/
|
|
89
|
+
async cancelSubscription(subscriptionId) {
|
|
90
|
+
try {
|
|
91
|
+
await this.stripe.subscriptions.cancel(subscriptionId);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
throw new MirageDevError(
|
|
94
|
+
"BILLING_STRIPE_ERROR",
|
|
95
|
+
`Failed to cancel subscription: ${error.message}`,
|
|
96
|
+
error
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// src/billing/index.ts
|
|
103
|
+
function getBillingProvider() {
|
|
104
|
+
const config = getConfig();
|
|
105
|
+
if (config.billing.provider === "stripe") {
|
|
106
|
+
if (!config.billing.stripeSecretKey) {
|
|
107
|
+
throw new Error("Stripe secret key is required");
|
|
108
|
+
}
|
|
109
|
+
return new StripeProvider(config.billing.stripeSecretKey);
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`Unsupported billing provider: ${config.billing.provider}`);
|
|
112
|
+
}
|
|
113
|
+
async function createCheckout(options) {
|
|
114
|
+
const provider = getBillingProvider();
|
|
115
|
+
return provider.createCheckoutSession(options);
|
|
116
|
+
}
|
|
117
|
+
async function createPortal(customerId, returnUrl) {
|
|
118
|
+
const provider = getBillingProvider();
|
|
119
|
+
return provider.createPortalSession(customerId, returnUrl);
|
|
120
|
+
}
|
|
121
|
+
async function getSubscription(subscriptionId) {
|
|
122
|
+
const provider = getBillingProvider();
|
|
123
|
+
return provider.getSubscription(subscriptionId);
|
|
124
|
+
}
|
|
125
|
+
async function cancelSubscription(subscriptionId) {
|
|
126
|
+
const provider = getBillingProvider();
|
|
127
|
+
return provider.cancelSubscription(subscriptionId);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { cancelSubscription, createCheckout, createPortal, getSubscription };
|