@coduckai/sdk 0.1.0 → 0.3.1

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.
@@ -1,14 +1,77 @@
1
+ import Stripe from 'stripe';
2
+
1
3
  /**
2
4
  * @coduckai/sdk/payments — Stripe Payments (server-only)
3
5
  *
4
- * Coming in v0.2.0. Wraps Stripe SDK with Connect destination charges.
6
+ * Wraps Stripe SDK with automatic Connect direct charges via stripeAccount header.
7
+ * Auto-reads STRIPE_SECRET_KEY, STRIPE_CONNECTED_ACCOUNT_ID, STRIPE_WEBHOOK_SECRET from env.
5
8
  */
9
+
10
+ interface CheckoutItem {
11
+ name: string;
12
+ /** Price in dollars (e.g. 29.99) */
13
+ price: number;
14
+ quantity?: number;
15
+ description?: string;
16
+ image?: string;
17
+ }
18
+ interface CreateCheckoutOptions {
19
+ items: CheckoutItem[];
20
+ successUrl: string;
21
+ cancelUrl: string;
22
+ customerEmail?: string;
23
+ metadata?: Record<string, string>;
24
+ /** Application fee in cents charged on top of the payment (Connect only) */
25
+ applicationFeeAmount?: number;
26
+ }
27
+ interface CreateSubscriptionOptions {
28
+ priceId: string;
29
+ successUrl: string;
30
+ cancelUrl: string;
31
+ customerEmail?: string;
32
+ trialDays?: number;
33
+ metadata?: Record<string, string>;
34
+ /** Application fee percentage for recurring charges (0-100, Connect only) */
35
+ applicationFeePercent?: number;
36
+ }
37
+ interface CheckoutResult {
38
+ url: string;
39
+ sessionId: string;
40
+ }
41
+ interface WebhookHandlers {
42
+ onCheckoutComplete?: (session: Stripe.Checkout.Session) => Promise<void> | void;
43
+ onSubscriptionCreated?: (subscription: Stripe.Subscription) => Promise<void> | void;
44
+ onSubscriptionUpdated?: (subscription: Stripe.Subscription) => Promise<void> | void;
45
+ onSubscriptionDeleted?: (subscription: Stripe.Subscription) => Promise<void> | void;
46
+ onPaymentSucceeded?: (invoice: Stripe.Invoice) => Promise<void> | void;
47
+ onPaymentFailed?: (invoice: Stripe.Invoice) => Promise<void> | void;
48
+ onChargeRefunded?: (charge: Stripe.Charge) => Promise<void> | void;
49
+ }
6
50
  declare const payments: {
7
- createCheckout: () => never;
8
- createSubscription: () => never;
9
- handleWebhook: () => never;
10
- webhookMiddleware: () => never;
11
- getStripe: () => never;
51
+ /**
52
+ * Create a Stripe Checkout Session for one-time payment.
53
+ * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.
54
+ */
55
+ createCheckout(options: CreateCheckoutOptions): Promise<CheckoutResult>;
56
+ /**
57
+ * Create a Stripe Checkout Session for subscriptions.
58
+ * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.
59
+ */
60
+ createSubscription(options: CreateSubscriptionOptions): Promise<CheckoutResult>;
61
+ /**
62
+ * Handle Stripe webhook events with typed handlers.
63
+ * Verifies the webhook signature and dispatches to your handler callbacks.
64
+ */
65
+ handleWebhook(req: any, handlers: WebhookHandlers): Promise<void>;
66
+ /**
67
+ * Express middleware for webhook routes.
68
+ * Applies express.raw() body parser — mount BEFORE any json() middleware.
69
+ */
70
+ webhookMiddleware(): any;
71
+ /**
72
+ * Get the underlying Stripe instance for advanced usage.
73
+ */
74
+ getStripe(): Stripe;
12
75
  };
13
76
 
14
- export { payments };
77
+ export { type CheckoutItem, type CheckoutResult, type CreateCheckoutOptions, type CreateSubscriptionOptions, type WebhookHandlers, payments };
@@ -1,14 +1,77 @@
1
+ import Stripe from 'stripe';
2
+
1
3
  /**
2
4
  * @coduckai/sdk/payments — Stripe Payments (server-only)
3
5
  *
4
- * Coming in v0.2.0. Wraps Stripe SDK with Connect destination charges.
6
+ * Wraps Stripe SDK with automatic Connect direct charges via stripeAccount header.
7
+ * Auto-reads STRIPE_SECRET_KEY, STRIPE_CONNECTED_ACCOUNT_ID, STRIPE_WEBHOOK_SECRET from env.
5
8
  */
9
+
10
+ interface CheckoutItem {
11
+ name: string;
12
+ /** Price in dollars (e.g. 29.99) */
13
+ price: number;
14
+ quantity?: number;
15
+ description?: string;
16
+ image?: string;
17
+ }
18
+ interface CreateCheckoutOptions {
19
+ items: CheckoutItem[];
20
+ successUrl: string;
21
+ cancelUrl: string;
22
+ customerEmail?: string;
23
+ metadata?: Record<string, string>;
24
+ /** Application fee in cents charged on top of the payment (Connect only) */
25
+ applicationFeeAmount?: number;
26
+ }
27
+ interface CreateSubscriptionOptions {
28
+ priceId: string;
29
+ successUrl: string;
30
+ cancelUrl: string;
31
+ customerEmail?: string;
32
+ trialDays?: number;
33
+ metadata?: Record<string, string>;
34
+ /** Application fee percentage for recurring charges (0-100, Connect only) */
35
+ applicationFeePercent?: number;
36
+ }
37
+ interface CheckoutResult {
38
+ url: string;
39
+ sessionId: string;
40
+ }
41
+ interface WebhookHandlers {
42
+ onCheckoutComplete?: (session: Stripe.Checkout.Session) => Promise<void> | void;
43
+ onSubscriptionCreated?: (subscription: Stripe.Subscription) => Promise<void> | void;
44
+ onSubscriptionUpdated?: (subscription: Stripe.Subscription) => Promise<void> | void;
45
+ onSubscriptionDeleted?: (subscription: Stripe.Subscription) => Promise<void> | void;
46
+ onPaymentSucceeded?: (invoice: Stripe.Invoice) => Promise<void> | void;
47
+ onPaymentFailed?: (invoice: Stripe.Invoice) => Promise<void> | void;
48
+ onChargeRefunded?: (charge: Stripe.Charge) => Promise<void> | void;
49
+ }
6
50
  declare const payments: {
7
- createCheckout: () => never;
8
- createSubscription: () => never;
9
- handleWebhook: () => never;
10
- webhookMiddleware: () => never;
11
- getStripe: () => never;
51
+ /**
52
+ * Create a Stripe Checkout Session for one-time payment.
53
+ * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.
54
+ */
55
+ createCheckout(options: CreateCheckoutOptions): Promise<CheckoutResult>;
56
+ /**
57
+ * Create a Stripe Checkout Session for subscriptions.
58
+ * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.
59
+ */
60
+ createSubscription(options: CreateSubscriptionOptions): Promise<CheckoutResult>;
61
+ /**
62
+ * Handle Stripe webhook events with typed handlers.
63
+ * Verifies the webhook signature and dispatches to your handler callbacks.
64
+ */
65
+ handleWebhook(req: any, handlers: WebhookHandlers): Promise<void>;
66
+ /**
67
+ * Express middleware for webhook routes.
68
+ * Applies express.raw() body parser — mount BEFORE any json() middleware.
69
+ */
70
+ webhookMiddleware(): any;
71
+ /**
72
+ * Get the underlying Stripe instance for advanced usage.
73
+ */
74
+ getStripe(): Stripe;
12
75
  };
13
76
 
14
- export { payments };
77
+ export { type CheckoutItem, type CheckoutResult, type CreateCheckoutOptions, type CreateSubscriptionOptions, type WebhookHandlers, payments };
@@ -1,3 +1,12 @@
1
+ import Stripe from 'stripe';
2
+
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined") return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
8
+ });
9
+
1
10
  // src/internal/env.ts
2
11
  function isServer() {
3
12
  return typeof window === "undefined";
@@ -10,20 +19,155 @@ function assertServer(moduleName) {
10
19
  }
11
20
  }
12
21
 
13
- // src/payments/index.ts
22
+ // src/internal/config.ts
23
+ var globalConfig = {};
24
+ function getConfig() {
25
+ return globalConfig;
26
+ }
14
27
  assertServer("payments");
28
+ var stripeInstance = null;
29
+ function getStripeInstance() {
30
+ if (stripeInstance) return stripeInstance;
31
+ const config = getConfig();
32
+ const secretKey = config.payments?.stripeSecretKey || process.env.STRIPE_SECRET_KEY;
33
+ if (!secretKey) {
34
+ throw new Error(
35
+ "@coduckai/sdk/payments: STRIPE_SECRET_KEY is required. Set the env var or call configure()."
36
+ );
37
+ }
38
+ stripeInstance = new Stripe(secretKey);
39
+ return stripeInstance;
40
+ }
41
+ function getConnectedAccountId() {
42
+ const config = getConfig();
43
+ return config.payments?.connectedAccountId || process.env.STRIPE_CONNECTED_ACCOUNT_ID || void 0;
44
+ }
45
+ function getWebhookSecret() {
46
+ const config = getConfig();
47
+ const secret = config.payments?.webhookSecret || process.env.STRIPE_WEBHOOK_SECRET;
48
+ if (!secret) {
49
+ throw new Error(
50
+ "@coduckai/sdk/payments: STRIPE_WEBHOOK_SECRET is required for webhook handling."
51
+ );
52
+ }
53
+ return secret;
54
+ }
15
55
  var payments = {
16
- createCheckout: notImplemented("payments.createCheckout"),
17
- createSubscription: notImplemented("payments.createSubscription"),
18
- handleWebhook: notImplemented("payments.handleWebhook"),
19
- webhookMiddleware: notImplemented("payments.webhookMiddleware"),
20
- getStripe: notImplemented("payments.getStripe")
56
+ /**
57
+ * Create a Stripe Checkout Session for one-time payment.
58
+ * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.
59
+ */
60
+ async createCheckout(options) {
61
+ const stripe = getStripeInstance();
62
+ const connectedAccountId = getConnectedAccountId();
63
+ const params = {
64
+ mode: "payment",
65
+ line_items: options.items.map((item) => ({
66
+ price_data: {
67
+ currency: "usd",
68
+ product_data: {
69
+ name: item.name,
70
+ ...item.description && { description: item.description },
71
+ ...item.image && { images: [item.image] }
72
+ },
73
+ unit_amount: Math.round(item.price * 100)
74
+ },
75
+ quantity: item.quantity || 1
76
+ })),
77
+ success_url: options.successUrl,
78
+ cancel_url: options.cancelUrl,
79
+ ...options.customerEmail && { customer_email: options.customerEmail },
80
+ ...options.metadata && { metadata: options.metadata }
81
+ };
82
+ if (connectedAccountId && options.applicationFeeAmount) {
83
+ params.payment_intent_data = {
84
+ application_fee_amount: options.applicationFeeAmount
85
+ };
86
+ }
87
+ const requestOptions = connectedAccountId ? { stripeAccount: connectedAccountId } : void 0;
88
+ const session = await stripe.checkout.sessions.create(params, requestOptions);
89
+ return { url: session.url, sessionId: session.id };
90
+ },
91
+ /**
92
+ * Create a Stripe Checkout Session for subscriptions.
93
+ * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.
94
+ */
95
+ async createSubscription(options) {
96
+ const stripe = getStripeInstance();
97
+ const connectedAccountId = getConnectedAccountId();
98
+ const params = {
99
+ mode: "subscription",
100
+ line_items: [{ price: options.priceId, quantity: 1 }],
101
+ success_url: options.successUrl,
102
+ cancel_url: options.cancelUrl,
103
+ ...options.customerEmail && { customer_email: options.customerEmail },
104
+ ...options.metadata && { metadata: options.metadata }
105
+ };
106
+ if (options.trialDays || connectedAccountId && options.applicationFeePercent) {
107
+ params.subscription_data = {};
108
+ if (options.trialDays) {
109
+ params.subscription_data.trial_period_days = options.trialDays;
110
+ }
111
+ if (connectedAccountId && options.applicationFeePercent) {
112
+ params.subscription_data.application_fee_percent = options.applicationFeePercent;
113
+ }
114
+ }
115
+ const requestOptions = connectedAccountId ? { stripeAccount: connectedAccountId } : void 0;
116
+ const session = await stripe.checkout.sessions.create(params, requestOptions);
117
+ return { url: session.url, sessionId: session.id };
118
+ },
119
+ /**
120
+ * Handle Stripe webhook events with typed handlers.
121
+ * Verifies the webhook signature and dispatches to your handler callbacks.
122
+ */
123
+ async handleWebhook(req, handlers) {
124
+ const stripe = getStripeInstance();
125
+ const webhookSecret = getWebhookSecret();
126
+ const sig = req.headers["stripe-signature"];
127
+ const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
128
+ switch (event.type) {
129
+ case "checkout.session.completed":
130
+ await handlers.onCheckoutComplete?.(event.data.object);
131
+ break;
132
+ case "customer.subscription.created":
133
+ await handlers.onSubscriptionCreated?.(event.data.object);
134
+ break;
135
+ case "customer.subscription.updated":
136
+ await handlers.onSubscriptionUpdated?.(event.data.object);
137
+ break;
138
+ case "customer.subscription.deleted":
139
+ await handlers.onSubscriptionDeleted?.(event.data.object);
140
+ break;
141
+ case "invoice.payment_succeeded":
142
+ await handlers.onPaymentSucceeded?.(event.data.object);
143
+ break;
144
+ case "invoice.payment_failed":
145
+ await handlers.onPaymentFailed?.(event.data.object);
146
+ break;
147
+ case "charge.refunded":
148
+ await handlers.onChargeRefunded?.(event.data.object);
149
+ break;
150
+ }
151
+ },
152
+ /**
153
+ * Express middleware for webhook routes.
154
+ * Applies express.raw() body parser — mount BEFORE any json() middleware.
155
+ */
156
+ webhookMiddleware() {
157
+ try {
158
+ const express = __require("express");
159
+ return express.raw({ type: "application/json" });
160
+ } catch {
161
+ return (_req, _res, next) => next();
162
+ }
163
+ },
164
+ /**
165
+ * Get the underlying Stripe instance for advanced usage.
166
+ */
167
+ getStripe() {
168
+ return getStripeInstance();
169
+ }
21
170
  };
22
- function notImplemented(name) {
23
- return () => {
24
- throw new Error(`@coduckai/sdk: ${name}() is not yet implemented. Coming in v0.2.0.`);
25
- };
26
- }
27
171
 
28
172
  export { payments };
29
173
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/internal/env.ts","../../src/payments/index.ts"],"names":[],"mappings":";AAgBO,SAAS,QAAA,GAAoB;AAClC,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,aAAa,UAAA,EAA0B;AACrD,EAAA,IAAI,CAAC,UAAS,EAAG;AACf,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,iBAAiB,UAAU,CAAA,2DAAA;AAAA,KAC7B;AAAA,EACF;AACF;;;ACnBA,YAAA,CAAa,UAAU,CAAA;AAEhB,IAAM,QAAA,GAAW;AAAA,EACtB,cAAA,EAAgB,eAAe,yBAAyB,CAAA;AAAA,EACxD,kBAAA,EAAoB,eAAe,6BAA6B,CAAA;AAAA,EAChE,aAAA,EAAe,eAAe,wBAAwB,CAAA;AAAA,EACtD,iBAAA,EAAmB,eAAe,4BAA4B,CAAA;AAAA,EAC9D,SAAA,EAAW,eAAe,oBAAoB;AAChD;AAEA,SAAS,eAAe,IAAA,EAAc;AACpC,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,4CAAA,CAA8C,CAAA;AAAA,EACtF,CAAA;AACF","file":"index.js","sourcesContent":["/**\n * Environment variable helpers\n */\n\nexport function getEnv(key: string, fallback?: string): string | undefined {\n return process.env[key] || fallback;\n}\n\nexport function requireEnv(key: string): string {\n const val = process.env[key];\n if (!val) {\n throw new Error(`@coduckai/sdk: Missing required environment variable: ${key}`);\n }\n return val;\n}\n\nexport function isServer(): boolean {\n return typeof window === 'undefined';\n}\n\nexport function assertServer(moduleName: string): void {\n if (!isServer()) {\n throw new Error(\n `@coduckai/sdk/${moduleName} is server-only. Use @coduckai/sdk/client for browser code.`\n );\n }\n}\n","/**\n * @coduckai/sdk/payments — Stripe Payments (server-only)\n *\n * Coming in v0.2.0. Wraps Stripe SDK with Connect destination charges.\n */\n\nimport { assertServer } from '../internal/env';\nassertServer('payments');\n\nexport const payments = {\n createCheckout: notImplemented('payments.createCheckout'),\n createSubscription: notImplemented('payments.createSubscription'),\n handleWebhook: notImplemented('payments.handleWebhook'),\n webhookMiddleware: notImplemented('payments.webhookMiddleware'),\n getStripe: notImplemented('payments.getStripe'),\n};\n\nfunction notImplemented(name: string) {\n return () => {\n throw new Error(`@coduckai/sdk: ${name}() is not yet implemented. Coming in v0.2.0.`);\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/internal/env.ts","../../src/internal/config.ts","../../src/payments/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Environment variable helpers\n */\n\nexport function getEnv(key: string, fallback?: string): string | undefined {\n return process.env[key] || fallback;\n}\n\nexport function requireEnv(key: string): string {\n const val = process.env[key];\n if (!val) {\n throw new Error(`@coduckai/sdk: Missing required environment variable: ${key}`);\n }\n return val;\n}\n\nexport function isServer(): boolean {\n return typeof window === 'undefined';\n}\n\nexport function assertServer(moduleName: string): void {\n if (!isServer()) {\n throw new Error(\n `@coduckai/sdk/${moduleName} is server-only. Use @coduckai/sdk/client for browser code.`\n );\n }\n}\n","/**\n * Global SDK configuration\n *\n * CoDuck apps use env vars automatically — no configure() needed.\n * Standalone usage can call configure() to override.\n */\n\nexport interface SDKConfig {\n auth?: {\n jwtSecret?: string;\n jwtExpiresIn?: string;\n bcryptRounds?: number;\n };\n db?: {\n connectionString?: string;\n };\n client?: {\n baseUrl?: string;\n tokenKey?: string;\n };\n payments?: {\n stripeSecretKey?: string;\n connectedAccountId?: string;\n webhookSecret?: string;\n };\n ai?: {\n provider?: 'openai' | 'anthropic';\n apiKey?: string;\n };\n}\n\nlet globalConfig: SDKConfig = {};\n\nexport function setConfig(config: SDKConfig): void {\n globalConfig = { ...globalConfig, ...config };\n}\n\nexport function getConfig(): SDKConfig {\n return globalConfig;\n}\n","/**\n * @coduckai/sdk/payments — Stripe Payments (server-only)\n *\n * Wraps Stripe SDK with automatic Connect direct charges via stripeAccount header.\n * Auto-reads STRIPE_SECRET_KEY, STRIPE_CONNECTED_ACCOUNT_ID, STRIPE_WEBHOOK_SECRET from env.\n */\n\nimport { assertServer } from '../internal/env';\nimport { getConfig } from '../internal/config';\nimport Stripe from 'stripe';\n\nassertServer('payments');\n\n// ---------------------------------------------------------------------------\n// Lazy singleton Stripe instance\n// ---------------------------------------------------------------------------\n\nlet stripeInstance: Stripe | null = null;\n\nfunction getStripeInstance(): Stripe {\n if (stripeInstance) return stripeInstance;\n\n const config = getConfig();\n const secretKey = config.payments?.stripeSecretKey || process.env.STRIPE_SECRET_KEY;\n\n if (!secretKey) {\n throw new Error(\n '@coduckai/sdk/payments: STRIPE_SECRET_KEY is required. Set the env var or call configure().'\n );\n }\n\n stripeInstance = new Stripe(secretKey);\n return stripeInstance;\n}\n\nfunction getConnectedAccountId(): string | undefined {\n const config = getConfig();\n return config.payments?.connectedAccountId || process.env.STRIPE_CONNECTED_ACCOUNT_ID || undefined;\n}\n\nfunction getWebhookSecret(): string {\n const config = getConfig();\n const secret = config.payments?.webhookSecret || process.env.STRIPE_WEBHOOK_SECRET;\n if (!secret) {\n throw new Error(\n '@coduckai/sdk/payments: STRIPE_WEBHOOK_SECRET is required for webhook handling.'\n );\n }\n return secret;\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface CheckoutItem {\n name: string;\n /** Price in dollars (e.g. 29.99) */\n price: number;\n quantity?: number;\n description?: string;\n image?: string;\n}\n\nexport interface CreateCheckoutOptions {\n items: CheckoutItem[];\n successUrl: string;\n cancelUrl: string;\n customerEmail?: string;\n metadata?: Record<string, string>;\n /** Application fee in cents charged on top of the payment (Connect only) */\n applicationFeeAmount?: number;\n}\n\nexport interface CreateSubscriptionOptions {\n priceId: string;\n successUrl: string;\n cancelUrl: string;\n customerEmail?: string;\n trialDays?: number;\n metadata?: Record<string, string>;\n /** Application fee percentage for recurring charges (0-100, Connect only) */\n applicationFeePercent?: number;\n}\n\nexport interface CheckoutResult {\n url: string;\n sessionId: string;\n}\n\nexport interface WebhookHandlers {\n onCheckoutComplete?: (session: Stripe.Checkout.Session) => Promise<void> | void;\n onSubscriptionCreated?: (subscription: Stripe.Subscription) => Promise<void> | void;\n onSubscriptionUpdated?: (subscription: Stripe.Subscription) => Promise<void> | void;\n onSubscriptionDeleted?: (subscription: Stripe.Subscription) => Promise<void> | void;\n onPaymentSucceeded?: (invoice: Stripe.Invoice) => Promise<void> | void;\n onPaymentFailed?: (invoice: Stripe.Invoice) => Promise<void> | void;\n onChargeRefunded?: (charge: Stripe.Charge) => Promise<void> | void;\n}\n\n// ---------------------------------------------------------------------------\n// Payments API\n// ---------------------------------------------------------------------------\n\nexport const payments = {\n /**\n * Create a Stripe Checkout Session for one-time payment.\n * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.\n */\n async createCheckout(options: CreateCheckoutOptions): Promise<CheckoutResult> {\n const stripe = getStripeInstance();\n const connectedAccountId = getConnectedAccountId();\n\n const params: Stripe.Checkout.SessionCreateParams = {\n mode: 'payment',\n line_items: options.items.map(item => ({\n price_data: {\n currency: 'usd',\n product_data: {\n name: item.name,\n ...(item.description && { description: item.description }),\n ...(item.image && { images: [item.image] }),\n },\n unit_amount: Math.round(item.price * 100),\n },\n quantity: item.quantity || 1,\n })),\n success_url: options.successUrl,\n cancel_url: options.cancelUrl,\n ...(options.customerEmail && { customer_email: options.customerEmail }),\n ...(options.metadata && { metadata: options.metadata }),\n };\n\n if (connectedAccountId && options.applicationFeeAmount) {\n params.payment_intent_data = {\n application_fee_amount: options.applicationFeeAmount,\n };\n }\n\n const requestOptions: Stripe.RequestOptions | undefined = connectedAccountId\n ? { stripeAccount: connectedAccountId }\n : undefined;\n\n const session = await stripe.checkout.sessions.create(params, requestOptions);\n\n return { url: session.url!, sessionId: session.id };\n },\n\n /**\n * Create a Stripe Checkout Session for subscriptions.\n * Automatically uses direct charges (stripeAccount) when STRIPE_CONNECTED_ACCOUNT_ID is set.\n */\n async createSubscription(options: CreateSubscriptionOptions): Promise<CheckoutResult> {\n const stripe = getStripeInstance();\n const connectedAccountId = getConnectedAccountId();\n\n const params: Stripe.Checkout.SessionCreateParams = {\n mode: 'subscription',\n line_items: [{ price: options.priceId, quantity: 1 }],\n success_url: options.successUrl,\n cancel_url: options.cancelUrl,\n ...(options.customerEmail && { customer_email: options.customerEmail }),\n ...(options.metadata && { metadata: options.metadata }),\n };\n\n if (options.trialDays || (connectedAccountId && options.applicationFeePercent)) {\n params.subscription_data = {};\n if (options.trialDays) {\n params.subscription_data.trial_period_days = options.trialDays;\n }\n if (connectedAccountId && options.applicationFeePercent) {\n params.subscription_data.application_fee_percent = options.applicationFeePercent;\n }\n }\n\n const requestOptions: Stripe.RequestOptions | undefined = connectedAccountId\n ? { stripeAccount: connectedAccountId }\n : undefined;\n\n const session = await stripe.checkout.sessions.create(params, requestOptions);\n\n return { url: session.url!, sessionId: session.id };\n },\n\n /**\n * Handle Stripe webhook events with typed handlers.\n * Verifies the webhook signature and dispatches to your handler callbacks.\n */\n async handleWebhook(req: any, handlers: WebhookHandlers): Promise<void> {\n const stripe = getStripeInstance();\n const webhookSecret = getWebhookSecret();\n\n const sig = req.headers['stripe-signature'];\n const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);\n\n switch (event.type) {\n case 'checkout.session.completed':\n await handlers.onCheckoutComplete?.(event.data.object as Stripe.Checkout.Session);\n break;\n case 'customer.subscription.created':\n await handlers.onSubscriptionCreated?.(event.data.object as Stripe.Subscription);\n break;\n case 'customer.subscription.updated':\n await handlers.onSubscriptionUpdated?.(event.data.object as Stripe.Subscription);\n break;\n case 'customer.subscription.deleted':\n await handlers.onSubscriptionDeleted?.(event.data.object as Stripe.Subscription);\n break;\n case 'invoice.payment_succeeded':\n await handlers.onPaymentSucceeded?.(event.data.object as Stripe.Invoice);\n break;\n case 'invoice.payment_failed':\n await handlers.onPaymentFailed?.(event.data.object as Stripe.Invoice);\n break;\n case 'charge.refunded':\n await handlers.onChargeRefunded?.(event.data.object as Stripe.Charge);\n break;\n }\n },\n\n /**\n * Express middleware for webhook routes.\n * Applies express.raw() body parser — mount BEFORE any json() middleware.\n */\n webhookMiddleware(): any {\n try {\n const express = require('express');\n return express.raw({ type: 'application/json' });\n } catch {\n return (_req: any, _res: any, next: any) => next();\n }\n },\n\n /**\n * Get the underlying Stripe instance for advanced usage.\n */\n getStripe(): Stripe {\n return getStripeInstance();\n },\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coduckai/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.3.1",
4
4
  "description": "CoDuck platform SDK — auth, database, payments, AI, and more for generated apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -60,31 +60,53 @@
60
60
  "prepublishOnly": "npm run build"
61
61
  },
62
62
  "dependencies": {
63
+ "axios": "^1.6.2",
63
64
  "bcrypt": "^5.1.1",
64
65
  "jsonwebtoken": "^9.0.2",
65
- "pg": "^8.11.3",
66
- "axios": "^1.6.2"
66
+ "pg": "^8.11.3"
67
67
  },
68
68
  "devDependencies": {
69
+ "@anthropic-ai/sdk": "^0.74.0",
69
70
  "@types/bcrypt": "^5.0.2",
70
- "@types/jsonwebtoken": "^9.0.7",
71
- "@types/pg": "^8.11.10",
72
71
  "@types/express": "^4.17.21",
72
+ "@types/jsonwebtoken": "^9.0.7",
73
73
  "@types/node": "^20.11.5",
74
+ "@types/pg": "^8.11.10",
74
75
  "express": "^4.18.2",
76
+ "openai": "^6.21.0",
77
+ "stripe": "^20.3.1",
75
78
  "tsup": "^8.0.1",
76
79
  "typescript": "^5.3.3",
77
80
  "vitest": "^1.2.0"
78
81
  },
79
82
  "peerDependencies": {
80
- "express": "^4.18.0"
83
+ "@anthropic-ai/sdk": ">=0.20.0",
84
+ "express": "^4.18.0",
85
+ "openai": ">=4.0.0",
86
+ "stripe": ">=14.0.0"
81
87
  },
82
88
  "peerDependenciesMeta": {
83
89
  "express": {
84
90
  "optional": true
91
+ },
92
+ "stripe": {
93
+ "optional": true
94
+ },
95
+ "openai": {
96
+ "optional": true
97
+ },
98
+ "@anthropic-ai/sdk": {
99
+ "optional": true
85
100
  }
86
101
  },
87
- "keywords": ["coduck", "sdk", "auth", "database", "payments", "ai"],
102
+ "keywords": [
103
+ "coduck",
104
+ "sdk",
105
+ "auth",
106
+ "database",
107
+ "payments",
108
+ "ai"
109
+ ],
88
110
  "license": "MIT",
89
111
  "repository": {
90
112
  "type": "git",