vibezcheck 0.4.0 → 0.4.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 +273 -203
- package/dist/ai-sdk/index.d.mts +6 -4
- package/dist/ai-sdk/index.d.ts +6 -4
- package/dist/ai-sdk/index.js +184 -22
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/ai-sdk/index.mjs +184 -22
- package/dist/ai-sdk/index.mjs.map +1 -1
- package/dist/cli/index.js +316 -17
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +316 -17
- package/dist/cli/index.mjs.map +1 -1
- package/dist/{client-kJN_Znan.d.ts → client-w_hWhQ6g.d.mts} +4 -2
- package/dist/{client--iq93FQg.d.mts → client-ynfWcHX6.d.ts} +4 -2
- package/dist/customers/index.d.mts +30 -4
- package/dist/customers/index.d.ts +30 -4
- package/dist/customers/index.js +108 -8
- package/dist/customers/index.js.map +1 -1
- package/dist/customers/index.mjs +106 -7
- package/dist/customers/index.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +238 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +237 -28
- package/dist/index.mjs.map +1 -1
- package/dist/meter/index.d.mts +2 -2
- package/dist/meter/index.d.ts +2 -2
- package/dist/meter/index.js +95 -16
- package/dist/meter/index.js.map +1 -1
- package/dist/meter/index.mjs +95 -16
- package/dist/meter/index.mjs.map +1 -1
- package/dist/pricing/index.d.mts +1 -1
- package/dist/pricing/index.d.ts +1 -1
- package/dist/react/index.d.mts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/{types-Zbzxg-Ka.d.mts → types-Mozk4-Mr.d.mts} +70 -12
- package/dist/{types-Zbzxg-Ka.d.ts → types-Mozk4-Mr.d.ts} +70 -12
- package/package.json +161 -153
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import Stripe from 'stripe';
|
|
2
|
+
import { d as CustomerInfo, C as CustomerParam } from '../types-Mozk4-Mr.js';
|
|
2
3
|
|
|
3
4
|
interface GetOrCreateCustomerParams {
|
|
4
|
-
userId
|
|
5
|
+
userId?: string;
|
|
5
6
|
email?: string;
|
|
6
7
|
name?: string;
|
|
7
|
-
|
|
8
|
+
phone?: string;
|
|
9
|
+
orgId?: string;
|
|
10
|
+
organizationId?: string;
|
|
11
|
+
orgName?: string;
|
|
12
|
+
teamId?: string;
|
|
13
|
+
workspaceId?: string;
|
|
14
|
+
role?: string;
|
|
15
|
+
plan?: string;
|
|
16
|
+
tier?: string;
|
|
17
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
18
|
+
[key: string]: any;
|
|
8
19
|
}
|
|
9
20
|
interface CustomerManagerOptions {
|
|
10
21
|
apiKey?: string;
|
|
@@ -16,13 +27,17 @@ declare class CustomerManager {
|
|
|
16
27
|
private cache;
|
|
17
28
|
constructor(options?: CustomerManagerOptions);
|
|
18
29
|
/**
|
|
19
|
-
* Retrieves existing Stripe Customer or automatically provisions a new one
|
|
30
|
+
* Retrieves existing Stripe Customer or automatically provisions a new one with full metadata
|
|
20
31
|
*/
|
|
21
32
|
getOrCreate(params: GetOrCreateCustomerParams): Promise<{
|
|
22
33
|
id: string;
|
|
23
34
|
isNew: boolean;
|
|
24
35
|
customer: Stripe.Customer;
|
|
25
36
|
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Updates an existing Stripe Customer's information and metadata
|
|
39
|
+
*/
|
|
40
|
+
updateCustomer(customerId: string, params: Partial<GetOrCreateCustomerParams>): Promise<Stripe.Customer>;
|
|
26
41
|
/**
|
|
27
42
|
* Clears in-memory resolution cache
|
|
28
43
|
*/
|
|
@@ -46,4 +61,15 @@ declare class CustomerCache {
|
|
|
46
61
|
clear(): void;
|
|
47
62
|
}
|
|
48
63
|
|
|
49
|
-
|
|
64
|
+
interface NormalizedCustomer {
|
|
65
|
+
customerId?: string;
|
|
66
|
+
customerEmail?: string;
|
|
67
|
+
customerObj?: CustomerInfo;
|
|
68
|
+
customerMetadata: Record<string, string | number | boolean>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Normalizes string or object customer into structured identifiers and metadata
|
|
72
|
+
*/
|
|
73
|
+
declare function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer;
|
|
74
|
+
|
|
75
|
+
export { CustomerCache, CustomerManager, type CustomerManagerOptions, type GetOrCreateCustomerParams, type NormalizedCustomer, createCustomerManager, normalizeCustomer };
|
package/dist/customers/index.js
CHANGED
|
@@ -32,7 +32,8 @@ var customers_exports = {};
|
|
|
32
32
|
__export(customers_exports, {
|
|
33
33
|
CustomerCache: () => CustomerCache,
|
|
34
34
|
CustomerManager: () => CustomerManager,
|
|
35
|
-
createCustomerManager: () => createCustomerManager
|
|
35
|
+
createCustomerManager: () => createCustomerManager,
|
|
36
|
+
normalizeCustomer: () => normalizeCustomer
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(customers_exports);
|
|
38
39
|
|
|
@@ -84,7 +85,7 @@ var CustomerManager = class {
|
|
|
84
85
|
this.cache = new CustomerCache(options.cacheTtlMs);
|
|
85
86
|
}
|
|
86
87
|
/**
|
|
87
|
-
* Retrieves existing Stripe Customer or automatically provisions a new one
|
|
88
|
+
* Retrieves existing Stripe Customer or automatically provisions a new one with full metadata
|
|
88
89
|
*/
|
|
89
90
|
async getOrCreate(params) {
|
|
90
91
|
const cacheKey = params.userId || params.email;
|
|
@@ -125,20 +126,66 @@ var CustomerManager = class {
|
|
|
125
126
|
return { id: customer.id, isNew: false, customer };
|
|
126
127
|
}
|
|
127
128
|
}
|
|
129
|
+
const orgId = params.orgId || params.organizationId;
|
|
130
|
+
const teamId = params.teamId || params.workspaceId;
|
|
131
|
+
const stripeMetadata = {
|
|
132
|
+
vibez_user_id: params.userId || "",
|
|
133
|
+
created_by: "vibezcheck"
|
|
134
|
+
};
|
|
135
|
+
if (orgId) stripeMetadata.org_id = String(orgId);
|
|
136
|
+
if (params.orgName) stripeMetadata.org_name = String(params.orgName);
|
|
137
|
+
if (teamId) stripeMetadata.team_id = String(teamId);
|
|
138
|
+
if (params.plan) stripeMetadata.plan = String(params.plan);
|
|
139
|
+
if (params.tier) stripeMetadata.tier = String(params.tier);
|
|
140
|
+
if (params.role) stripeMetadata.role = String(params.role);
|
|
141
|
+
if (params.metadata) {
|
|
142
|
+
for (const [k, v] of Object.entries(params.metadata)) {
|
|
143
|
+
if (v !== void 0 && v !== null) {
|
|
144
|
+
stripeMetadata[k] = String(v);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
128
148
|
const newCustomer = await this.stripe.customers.create({
|
|
129
149
|
email: params.email,
|
|
130
150
|
name: params.name,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
created_by: "vibezcheck",
|
|
134
|
-
...params.metadata || {}
|
|
135
|
-
}
|
|
151
|
+
phone: params.phone,
|
|
152
|
+
metadata: stripeMetadata
|
|
136
153
|
});
|
|
137
154
|
if (cacheKey) this.cache.set(cacheKey, newCustomer.id);
|
|
138
155
|
if (params.userId) this.cache.set(params.userId, newCustomer.id);
|
|
139
156
|
if (params.email) this.cache.set(params.email, newCustomer.id);
|
|
140
157
|
return { id: newCustomer.id, isNew: true, customer: newCustomer };
|
|
141
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Updates an existing Stripe Customer's information and metadata
|
|
161
|
+
*/
|
|
162
|
+
async updateCustomer(customerId, params) {
|
|
163
|
+
const updatePayload = {};
|
|
164
|
+
if (params.email) updatePayload.email = params.email;
|
|
165
|
+
if (params.name) updatePayload.name = params.name;
|
|
166
|
+
if (params.phone) updatePayload.phone = params.phone;
|
|
167
|
+
const metadataToUpdate = {};
|
|
168
|
+
if (params.userId) metadataToUpdate.vibez_user_id = params.userId;
|
|
169
|
+
const orgId = params.orgId || params.organizationId;
|
|
170
|
+
if (orgId) metadataToUpdate.org_id = String(orgId);
|
|
171
|
+
if (params.orgName) metadataToUpdate.org_name = String(params.orgName);
|
|
172
|
+
const teamId = params.teamId || params.workspaceId;
|
|
173
|
+
if (teamId) metadataToUpdate.team_id = String(teamId);
|
|
174
|
+
if (params.plan) metadataToUpdate.plan = String(params.plan);
|
|
175
|
+
if (params.tier) metadataToUpdate.tier = String(params.tier);
|
|
176
|
+
if (params.role) metadataToUpdate.role = String(params.role);
|
|
177
|
+
if (params.metadata) {
|
|
178
|
+
for (const [k, v] of Object.entries(params.metadata)) {
|
|
179
|
+
if (v !== void 0 && v !== null) {
|
|
180
|
+
metadataToUpdate[k] = String(v);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (Object.keys(metadataToUpdate).length > 0) {
|
|
185
|
+
updatePayload.metadata = metadataToUpdate;
|
|
186
|
+
}
|
|
187
|
+
return await this.stripe.customers.update(customerId, updatePayload);
|
|
188
|
+
}
|
|
142
189
|
/**
|
|
143
190
|
* Clears in-memory resolution cache
|
|
144
191
|
*/
|
|
@@ -149,10 +196,63 @@ var CustomerManager = class {
|
|
|
149
196
|
function createCustomerManager(options = {}) {
|
|
150
197
|
return new CustomerManager(options);
|
|
151
198
|
}
|
|
199
|
+
|
|
200
|
+
// src/customers/helpers.ts
|
|
201
|
+
function normalizeCustomer(customer, extraCustomerId) {
|
|
202
|
+
if (!customer && !extraCustomerId) {
|
|
203
|
+
return {
|
|
204
|
+
customerId: void 0,
|
|
205
|
+
customerEmail: void 0,
|
|
206
|
+
customerObj: void 0,
|
|
207
|
+
customerMetadata: {}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (typeof customer === "string") {
|
|
211
|
+
const isEmail = customer.includes("@");
|
|
212
|
+
const customerObj2 = {
|
|
213
|
+
id: customer,
|
|
214
|
+
email: isEmail ? customer : void 0
|
|
215
|
+
};
|
|
216
|
+
return {
|
|
217
|
+
customerId: customer,
|
|
218
|
+
customerEmail: isEmail ? customer : void 0,
|
|
219
|
+
customerObj: customerObj2,
|
|
220
|
+
customerMetadata: {}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : void 0);
|
|
224
|
+
const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;
|
|
225
|
+
const customerEmail = customerObj?.email;
|
|
226
|
+
const customerMetadata = {};
|
|
227
|
+
if (customerObj) {
|
|
228
|
+
const orgId = customerObj.orgId || customerObj.organizationId;
|
|
229
|
+
if (orgId) customerMetadata.org_id = String(orgId);
|
|
230
|
+
const teamId = customerObj.teamId || customerObj.workspaceId;
|
|
231
|
+
if (teamId) customerMetadata.team_id = String(teamId);
|
|
232
|
+
if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);
|
|
233
|
+
if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);
|
|
234
|
+
if (customerObj.role) customerMetadata.role = String(customerObj.role);
|
|
235
|
+
if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);
|
|
236
|
+
if (customerObj.metadata) {
|
|
237
|
+
for (const [key, val] of Object.entries(customerObj.metadata)) {
|
|
238
|
+
if (val !== null && val !== void 0) {
|
|
239
|
+
customerMetadata[key] = val;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
customerId,
|
|
246
|
+
customerEmail,
|
|
247
|
+
customerObj,
|
|
248
|
+
customerMetadata
|
|
249
|
+
};
|
|
250
|
+
}
|
|
152
251
|
// Annotate the CommonJS export names for ESM import in node:
|
|
153
252
|
0 && (module.exports = {
|
|
154
253
|
CustomerCache,
|
|
155
254
|
CustomerManager,
|
|
156
|
-
createCustomerManager
|
|
255
|
+
createCustomerManager,
|
|
256
|
+
normalizeCustomer
|
|
157
257
|
});
|
|
158
258
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/customers/index.ts","../../src/customers/manager.ts","../../src/customers/cache.ts"],"sourcesContent":["export * from './manager';\nexport * from './cache';\n","import Stripe from 'stripe';\nimport { CustomerCache } from './cache';\n\nexport interface GetOrCreateCustomerParams {\n userId: string;\n email?: string;\n name?: string;\n metadata?: Record<string, string>;\n}\n\nexport interface CustomerManagerOptions {\n apiKey?: string;\n stripe?: Stripe;\n cacheTtlMs?: number;\n}\n\nexport class CustomerManager {\n private stripe: Stripe;\n private cache: CustomerCache;\n\n constructor(options: CustomerManagerOptions = {}) {\n if (options.stripe) {\n this.stripe = options.stripe;\n } else {\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\n if (!apiKey) {\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\n }\n this.stripe = new Stripe(apiKey);\n }\n\n this.cache = new CustomerCache(options.cacheTtlMs);\n }\n\n /**\n * Retrieves existing Stripe Customer or automatically provisions a new one\n */\n public async getOrCreate(\n params: GetOrCreateCustomerParams\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\n const cacheKey = params.userId || params.email;\n if (cacheKey) {\n const cachedId = this.cache.get(cacheKey);\n if (cachedId) {\n return {\n id: cachedId,\n isNew: false,\n customer: { id: cachedId } as Stripe.Customer,\n };\n }\n }\n\n // 1. Search by userId in Stripe metadata\n if (params.userId) {\n try {\n const searchResult = await this.stripe.customers.search({\n query: `metadata['vibez_user_id']:'${params.userId}'`,\n limit: 1,\n });\n\n if (searchResult.data.length > 0) {\n const customer = searchResult.data[0];\n if (cacheKey) this.cache.set(cacheKey, customer.id);\n if (params.email) this.cache.set(params.email, customer.id);\n return { id: customer.id, isNew: false, customer };\n }\n } catch {\n // Fallback to email search if search query is unsupported or errors\n }\n }\n\n // 2. Search by email if provided\n if (params.email) {\n const listResult = await this.stripe.customers.list({\n email: params.email,\n limit: 1,\n });\n\n if (listResult.data.length > 0) {\n const customer = listResult.data[0];\n if (cacheKey) this.cache.set(cacheKey, customer.id);\n if (params.userId) this.cache.set(params.userId, customer.id);\n return { id: customer.id, isNew: false, customer };\n }\n }\n\n // 3. Create new Customer in Stripe\n const newCustomer = await this.stripe.customers.create({\n email: params.email,\n name: params.name,\n metadata: {\n vibez_user_id: params.userId,\n created_by: 'vibezcheck',\n ...(params.metadata || {}),\n },\n });\n\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\n if (params.email) this.cache.set(params.email, newCustomer.id);\n\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\n }\n\n /**\n * Clears in-memory resolution cache\n */\n public clearCache(): void {\n this.cache.clear();\n }\n}\n\n/**\n * Factory to create CustomerManager\n */\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\n return new CustomerManager(options);\n}\n","interface CacheEntry {\n customerId: string;\n expiresAt: number;\n}\n\n/**\n * In-memory Customer Resolution Cache with TTL\n */\nexport class CustomerCache {\n private cache = new Map<string, CacheEntry>();\n private readonly defaultTtlMs: number;\n\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\n // Default TTL: 1 hour\n this.defaultTtlMs = defaultTtlMs;\n }\n\n public get(key: string): string | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.customerId;\n }\n\n public set(key: string, customerId: string, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\n this.cache.set(key, { customerId, expiresAt });\n }\n\n public delete(key: string): void {\n this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n"],"mappings":"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","names":["Stripe"]}
|
|
1
|
+
{"version":3,"sources":["../../src/customers/index.ts","../../src/customers/manager.ts","../../src/customers/cache.ts","../../src/customers/helpers.ts"],"sourcesContent":["export * from './manager';\r\nexport * from './cache';\r\nexport * from './helpers';\r\n","import Stripe from 'stripe';\r\nimport { CustomerCache } from './cache';\r\n\r\nexport interface GetOrCreateCustomerParams {\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n phone?: string;\r\n orgId?: string;\r\n organizationId?: string;\r\n orgName?: string;\r\n teamId?: string;\r\n workspaceId?: string;\r\n role?: string;\r\n plan?: string;\r\n tier?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface CustomerManagerOptions {\r\n apiKey?: string;\r\n stripe?: Stripe;\r\n cacheTtlMs?: number;\r\n}\r\n\r\nexport class CustomerManager {\r\n private stripe: Stripe;\r\n private cache: CustomerCache;\r\n\r\n constructor(options: CustomerManagerOptions = {}) {\r\n if (options.stripe) {\r\n this.stripe = options.stripe;\r\n } else {\r\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\r\n if (!apiKey) {\r\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\r\n }\r\n this.stripe = new Stripe(apiKey);\r\n }\r\n\r\n this.cache = new CustomerCache(options.cacheTtlMs);\r\n }\r\n\r\n /**\r\n * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata\r\n */\r\n public async getOrCreate(\r\n params: GetOrCreateCustomerParams\r\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\r\n const cacheKey = params.userId || params.email;\r\n if (cacheKey) {\r\n const cachedId = this.cache.get(cacheKey);\r\n if (cachedId) {\r\n return {\r\n id: cachedId,\r\n isNew: false,\r\n customer: { id: cachedId } as Stripe.Customer,\r\n };\r\n }\r\n }\r\n\r\n // 1. Search by userId in Stripe metadata\r\n if (params.userId) {\r\n try {\r\n const searchResult = await this.stripe.customers.search({\r\n query: `metadata['vibez_user_id']:'${params.userId}'`,\r\n limit: 1,\r\n });\r\n\r\n if (searchResult.data.length > 0) {\r\n const customer = searchResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.email) this.cache.set(params.email, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n } catch {\r\n // Fallback to email search if search query is unsupported or errors\r\n }\r\n }\r\n\r\n // 2. Search by email if provided\r\n if (params.email) {\r\n const listResult = await this.stripe.customers.list({\r\n email: params.email,\r\n limit: 1,\r\n });\r\n\r\n if (listResult.data.length > 0) {\r\n const customer = listResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.userId) this.cache.set(params.userId, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n }\r\n\r\n // 3. Prepare rich metadata for Stripe Customer\r\n const orgId = params.orgId || params.organizationId;\r\n const teamId = params.teamId || params.workspaceId;\r\n\r\n const stripeMetadata: Record<string, string> = {\r\n vibez_user_id: params.userId || '',\r\n created_by: 'vibezcheck',\r\n };\r\n\r\n if (orgId) stripeMetadata.org_id = String(orgId);\r\n if (params.orgName) stripeMetadata.org_name = String(params.orgName);\r\n if (teamId) stripeMetadata.team_id = String(teamId);\r\n if (params.plan) stripeMetadata.plan = String(params.plan);\r\n if (params.tier) stripeMetadata.tier = String(params.tier);\r\n if (params.role) stripeMetadata.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n stripeMetadata[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n // 4. Create new Customer in Stripe\r\n const newCustomer = await this.stripe.customers.create({\r\n email: params.email,\r\n name: params.name,\r\n phone: params.phone,\r\n metadata: stripeMetadata,\r\n });\r\n\r\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\r\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\r\n if (params.email) this.cache.set(params.email, newCustomer.id);\r\n\r\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\r\n }\r\n\r\n /**\r\n * Updates an existing Stripe Customer's information and metadata\r\n */\r\n public async updateCustomer(\r\n customerId: string,\r\n params: Partial<GetOrCreateCustomerParams>\r\n ): Promise<Stripe.Customer> {\r\n const updatePayload: Stripe.CustomerUpdateParams = {};\r\n\r\n if (params.email) updatePayload.email = params.email;\r\n if (params.name) updatePayload.name = params.name;\r\n if (params.phone) updatePayload.phone = params.phone;\r\n\r\n const metadataToUpdate: Record<string, string> = {};\r\n if (params.userId) metadataToUpdate.vibez_user_id = params.userId;\r\n const orgId = params.orgId || params.organizationId;\r\n if (orgId) metadataToUpdate.org_id = String(orgId);\r\n if (params.orgName) metadataToUpdate.org_name = String(params.orgName);\r\n const teamId = params.teamId || params.workspaceId;\r\n if (teamId) metadataToUpdate.team_id = String(teamId);\r\n if (params.plan) metadataToUpdate.plan = String(params.plan);\r\n if (params.tier) metadataToUpdate.tier = String(params.tier);\r\n if (params.role) metadataToUpdate.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n metadataToUpdate[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n if (Object.keys(metadataToUpdate).length > 0) {\r\n updatePayload.metadata = metadataToUpdate;\r\n }\r\n\r\n return await this.stripe.customers.update(customerId, updatePayload);\r\n }\r\n\r\n /**\r\n * Clears in-memory resolution cache\r\n */\r\n public clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory to create CustomerManager\r\n */\r\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\r\n return new CustomerManager(options);\r\n}\r\n","interface CacheEntry {\n customerId: string;\n expiresAt: number;\n}\n\n/**\n * In-memory Customer Resolution Cache with TTL\n */\nexport class CustomerCache {\n private cache = new Map<string, CacheEntry>();\n private readonly defaultTtlMs: number;\n\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\n // Default TTL: 1 hour\n this.defaultTtlMs = defaultTtlMs;\n }\n\n public get(key: string): string | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.customerId;\n }\n\n public set(key: string, customerId: string, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\n this.cache.set(key, { customerId, expiresAt });\n }\n\n public delete(key: string): void {\n this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n"],"mappings":"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","names":["Stripe","customerObj"]}
|
package/dist/customers/index.mjs
CHANGED
|
@@ -46,7 +46,7 @@ var CustomerManager = class {
|
|
|
46
46
|
this.cache = new CustomerCache(options.cacheTtlMs);
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
|
-
* Retrieves existing Stripe Customer or automatically provisions a new one
|
|
49
|
+
* Retrieves existing Stripe Customer or automatically provisions a new one with full metadata
|
|
50
50
|
*/
|
|
51
51
|
async getOrCreate(params) {
|
|
52
52
|
const cacheKey = params.userId || params.email;
|
|
@@ -87,20 +87,66 @@ var CustomerManager = class {
|
|
|
87
87
|
return { id: customer.id, isNew: false, customer };
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
const orgId = params.orgId || params.organizationId;
|
|
91
|
+
const teamId = params.teamId || params.workspaceId;
|
|
92
|
+
const stripeMetadata = {
|
|
93
|
+
vibez_user_id: params.userId || "",
|
|
94
|
+
created_by: "vibezcheck"
|
|
95
|
+
};
|
|
96
|
+
if (orgId) stripeMetadata.org_id = String(orgId);
|
|
97
|
+
if (params.orgName) stripeMetadata.org_name = String(params.orgName);
|
|
98
|
+
if (teamId) stripeMetadata.team_id = String(teamId);
|
|
99
|
+
if (params.plan) stripeMetadata.plan = String(params.plan);
|
|
100
|
+
if (params.tier) stripeMetadata.tier = String(params.tier);
|
|
101
|
+
if (params.role) stripeMetadata.role = String(params.role);
|
|
102
|
+
if (params.metadata) {
|
|
103
|
+
for (const [k, v] of Object.entries(params.metadata)) {
|
|
104
|
+
if (v !== void 0 && v !== null) {
|
|
105
|
+
stripeMetadata[k] = String(v);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
90
109
|
const newCustomer = await this.stripe.customers.create({
|
|
91
110
|
email: params.email,
|
|
92
111
|
name: params.name,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
created_by: "vibezcheck",
|
|
96
|
-
...params.metadata || {}
|
|
97
|
-
}
|
|
112
|
+
phone: params.phone,
|
|
113
|
+
metadata: stripeMetadata
|
|
98
114
|
});
|
|
99
115
|
if (cacheKey) this.cache.set(cacheKey, newCustomer.id);
|
|
100
116
|
if (params.userId) this.cache.set(params.userId, newCustomer.id);
|
|
101
117
|
if (params.email) this.cache.set(params.email, newCustomer.id);
|
|
102
118
|
return { id: newCustomer.id, isNew: true, customer: newCustomer };
|
|
103
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Updates an existing Stripe Customer's information and metadata
|
|
122
|
+
*/
|
|
123
|
+
async updateCustomer(customerId, params) {
|
|
124
|
+
const updatePayload = {};
|
|
125
|
+
if (params.email) updatePayload.email = params.email;
|
|
126
|
+
if (params.name) updatePayload.name = params.name;
|
|
127
|
+
if (params.phone) updatePayload.phone = params.phone;
|
|
128
|
+
const metadataToUpdate = {};
|
|
129
|
+
if (params.userId) metadataToUpdate.vibez_user_id = params.userId;
|
|
130
|
+
const orgId = params.orgId || params.organizationId;
|
|
131
|
+
if (orgId) metadataToUpdate.org_id = String(orgId);
|
|
132
|
+
if (params.orgName) metadataToUpdate.org_name = String(params.orgName);
|
|
133
|
+
const teamId = params.teamId || params.workspaceId;
|
|
134
|
+
if (teamId) metadataToUpdate.team_id = String(teamId);
|
|
135
|
+
if (params.plan) metadataToUpdate.plan = String(params.plan);
|
|
136
|
+
if (params.tier) metadataToUpdate.tier = String(params.tier);
|
|
137
|
+
if (params.role) metadataToUpdate.role = String(params.role);
|
|
138
|
+
if (params.metadata) {
|
|
139
|
+
for (const [k, v] of Object.entries(params.metadata)) {
|
|
140
|
+
if (v !== void 0 && v !== null) {
|
|
141
|
+
metadataToUpdate[k] = String(v);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (Object.keys(metadataToUpdate).length > 0) {
|
|
146
|
+
updatePayload.metadata = metadataToUpdate;
|
|
147
|
+
}
|
|
148
|
+
return await this.stripe.customers.update(customerId, updatePayload);
|
|
149
|
+
}
|
|
104
150
|
/**
|
|
105
151
|
* Clears in-memory resolution cache
|
|
106
152
|
*/
|
|
@@ -111,9 +157,62 @@ var CustomerManager = class {
|
|
|
111
157
|
function createCustomerManager(options = {}) {
|
|
112
158
|
return new CustomerManager(options);
|
|
113
159
|
}
|
|
160
|
+
|
|
161
|
+
// src/customers/helpers.ts
|
|
162
|
+
function normalizeCustomer(customer, extraCustomerId) {
|
|
163
|
+
if (!customer && !extraCustomerId) {
|
|
164
|
+
return {
|
|
165
|
+
customerId: void 0,
|
|
166
|
+
customerEmail: void 0,
|
|
167
|
+
customerObj: void 0,
|
|
168
|
+
customerMetadata: {}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (typeof customer === "string") {
|
|
172
|
+
const isEmail = customer.includes("@");
|
|
173
|
+
const customerObj2 = {
|
|
174
|
+
id: customer,
|
|
175
|
+
email: isEmail ? customer : void 0
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
customerId: customer,
|
|
179
|
+
customerEmail: isEmail ? customer : void 0,
|
|
180
|
+
customerObj: customerObj2,
|
|
181
|
+
customerMetadata: {}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : void 0);
|
|
185
|
+
const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;
|
|
186
|
+
const customerEmail = customerObj?.email;
|
|
187
|
+
const customerMetadata = {};
|
|
188
|
+
if (customerObj) {
|
|
189
|
+
const orgId = customerObj.orgId || customerObj.organizationId;
|
|
190
|
+
if (orgId) customerMetadata.org_id = String(orgId);
|
|
191
|
+
const teamId = customerObj.teamId || customerObj.workspaceId;
|
|
192
|
+
if (teamId) customerMetadata.team_id = String(teamId);
|
|
193
|
+
if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);
|
|
194
|
+
if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);
|
|
195
|
+
if (customerObj.role) customerMetadata.role = String(customerObj.role);
|
|
196
|
+
if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);
|
|
197
|
+
if (customerObj.metadata) {
|
|
198
|
+
for (const [key, val] of Object.entries(customerObj.metadata)) {
|
|
199
|
+
if (val !== null && val !== void 0) {
|
|
200
|
+
customerMetadata[key] = val;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
customerId,
|
|
207
|
+
customerEmail,
|
|
208
|
+
customerObj,
|
|
209
|
+
customerMetadata
|
|
210
|
+
};
|
|
211
|
+
}
|
|
114
212
|
export {
|
|
115
213
|
CustomerCache,
|
|
116
214
|
CustomerManager,
|
|
117
|
-
createCustomerManager
|
|
215
|
+
createCustomerManager,
|
|
216
|
+
normalizeCustomer
|
|
118
217
|
};
|
|
119
218
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/customers/manager.ts","../../src/customers/cache.ts"],"sourcesContent":["import Stripe from 'stripe';\nimport { CustomerCache } from './cache';\n\nexport interface GetOrCreateCustomerParams {\n userId: string;\n email?: string;\n name?: string;\n metadata?: Record<string, string>;\n}\n\nexport interface CustomerManagerOptions {\n apiKey?: string;\n stripe?: Stripe;\n cacheTtlMs?: number;\n}\n\nexport class CustomerManager {\n private stripe: Stripe;\n private cache: CustomerCache;\n\n constructor(options: CustomerManagerOptions = {}) {\n if (options.stripe) {\n this.stripe = options.stripe;\n } else {\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\n if (!apiKey) {\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\n }\n this.stripe = new Stripe(apiKey);\n }\n\n this.cache = new CustomerCache(options.cacheTtlMs);\n }\n\n /**\n * Retrieves existing Stripe Customer or automatically provisions a new one\n */\n public async getOrCreate(\n params: GetOrCreateCustomerParams\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\n const cacheKey = params.userId || params.email;\n if (cacheKey) {\n const cachedId = this.cache.get(cacheKey);\n if (cachedId) {\n return {\n id: cachedId,\n isNew: false,\n customer: { id: cachedId } as Stripe.Customer,\n };\n }\n }\n\n // 1. Search by userId in Stripe metadata\n if (params.userId) {\n try {\n const searchResult = await this.stripe.customers.search({\n query: `metadata['vibez_user_id']:'${params.userId}'`,\n limit: 1,\n });\n\n if (searchResult.data.length > 0) {\n const customer = searchResult.data[0];\n if (cacheKey) this.cache.set(cacheKey, customer.id);\n if (params.email) this.cache.set(params.email, customer.id);\n return { id: customer.id, isNew: false, customer };\n }\n } catch {\n // Fallback to email search if search query is unsupported or errors\n }\n }\n\n // 2. Search by email if provided\n if (params.email) {\n const listResult = await this.stripe.customers.list({\n email: params.email,\n limit: 1,\n });\n\n if (listResult.data.length > 0) {\n const customer = listResult.data[0];\n if (cacheKey) this.cache.set(cacheKey, customer.id);\n if (params.userId) this.cache.set(params.userId, customer.id);\n return { id: customer.id, isNew: false, customer };\n }\n }\n\n // 3. Create new Customer in Stripe\n const newCustomer = await this.stripe.customers.create({\n email: params.email,\n name: params.name,\n metadata: {\n vibez_user_id: params.userId,\n created_by: 'vibezcheck',\n ...(params.metadata || {}),\n },\n });\n\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\n if (params.email) this.cache.set(params.email, newCustomer.id);\n\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\n }\n\n /**\n * Clears in-memory resolution cache\n */\n public clearCache(): void {\n this.cache.clear();\n }\n}\n\n/**\n * Factory to create CustomerManager\n */\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\n return new CustomerManager(options);\n}\n","interface CacheEntry {\n customerId: string;\n expiresAt: number;\n}\n\n/**\n * In-memory Customer Resolution Cache with TTL\n */\nexport class CustomerCache {\n private cache = new Map<string, CacheEntry>();\n private readonly defaultTtlMs: number;\n\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\n // Default TTL: 1 hour\n this.defaultTtlMs = defaultTtlMs;\n }\n\n public get(key: string): string | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.customerId;\n }\n\n public set(key: string, customerId: string, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\n this.cache.set(key, { customerId, expiresAt });\n }\n\n public delete(key: string): void {\n this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/customers/manager.ts","../../src/customers/cache.ts","../../src/customers/helpers.ts"],"sourcesContent":["import Stripe from 'stripe';\r\nimport { CustomerCache } from './cache';\r\n\r\nexport interface GetOrCreateCustomerParams {\r\n userId?: string;\r\n email?: string;\r\n name?: string;\r\n phone?: string;\r\n orgId?: string;\r\n organizationId?: string;\r\n orgName?: string;\r\n teamId?: string;\r\n workspaceId?: string;\r\n role?: string;\r\n plan?: string;\r\n tier?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n [key: string]: any;\r\n}\r\n\r\nexport interface CustomerManagerOptions {\r\n apiKey?: string;\r\n stripe?: Stripe;\r\n cacheTtlMs?: number;\r\n}\r\n\r\nexport class CustomerManager {\r\n private stripe: Stripe;\r\n private cache: CustomerCache;\r\n\r\n constructor(options: CustomerManagerOptions = {}) {\r\n if (options.stripe) {\r\n this.stripe = options.stripe;\r\n } else {\r\n const apiKey = options.apiKey || process.env.STRIPE_SECRET_KEY;\r\n if (!apiKey) {\r\n throw new Error('[vibezcheck] Stripe API key required for customer management.');\r\n }\r\n this.stripe = new Stripe(apiKey);\r\n }\r\n\r\n this.cache = new CustomerCache(options.cacheTtlMs);\r\n }\r\n\r\n /**\r\n * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata\r\n */\r\n public async getOrCreate(\r\n params: GetOrCreateCustomerParams\r\n ): Promise<{ id: string; isNew: boolean; customer: Stripe.Customer }> {\r\n const cacheKey = params.userId || params.email;\r\n if (cacheKey) {\r\n const cachedId = this.cache.get(cacheKey);\r\n if (cachedId) {\r\n return {\r\n id: cachedId,\r\n isNew: false,\r\n customer: { id: cachedId } as Stripe.Customer,\r\n };\r\n }\r\n }\r\n\r\n // 1. Search by userId in Stripe metadata\r\n if (params.userId) {\r\n try {\r\n const searchResult = await this.stripe.customers.search({\r\n query: `metadata['vibez_user_id']:'${params.userId}'`,\r\n limit: 1,\r\n });\r\n\r\n if (searchResult.data.length > 0) {\r\n const customer = searchResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.email) this.cache.set(params.email, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n } catch {\r\n // Fallback to email search if search query is unsupported or errors\r\n }\r\n }\r\n\r\n // 2. Search by email if provided\r\n if (params.email) {\r\n const listResult = await this.stripe.customers.list({\r\n email: params.email,\r\n limit: 1,\r\n });\r\n\r\n if (listResult.data.length > 0) {\r\n const customer = listResult.data[0];\r\n if (cacheKey) this.cache.set(cacheKey, customer.id);\r\n if (params.userId) this.cache.set(params.userId, customer.id);\r\n return { id: customer.id, isNew: false, customer };\r\n }\r\n }\r\n\r\n // 3. Prepare rich metadata for Stripe Customer\r\n const orgId = params.orgId || params.organizationId;\r\n const teamId = params.teamId || params.workspaceId;\r\n\r\n const stripeMetadata: Record<string, string> = {\r\n vibez_user_id: params.userId || '',\r\n created_by: 'vibezcheck',\r\n };\r\n\r\n if (orgId) stripeMetadata.org_id = String(orgId);\r\n if (params.orgName) stripeMetadata.org_name = String(params.orgName);\r\n if (teamId) stripeMetadata.team_id = String(teamId);\r\n if (params.plan) stripeMetadata.plan = String(params.plan);\r\n if (params.tier) stripeMetadata.tier = String(params.tier);\r\n if (params.role) stripeMetadata.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n stripeMetadata[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n // 4. Create new Customer in Stripe\r\n const newCustomer = await this.stripe.customers.create({\r\n email: params.email,\r\n name: params.name,\r\n phone: params.phone,\r\n metadata: stripeMetadata,\r\n });\r\n\r\n if (cacheKey) this.cache.set(cacheKey, newCustomer.id);\r\n if (params.userId) this.cache.set(params.userId, newCustomer.id);\r\n if (params.email) this.cache.set(params.email, newCustomer.id);\r\n\r\n return { id: newCustomer.id, isNew: true, customer: newCustomer };\r\n }\r\n\r\n /**\r\n * Updates an existing Stripe Customer's information and metadata\r\n */\r\n public async updateCustomer(\r\n customerId: string,\r\n params: Partial<GetOrCreateCustomerParams>\r\n ): Promise<Stripe.Customer> {\r\n const updatePayload: Stripe.CustomerUpdateParams = {};\r\n\r\n if (params.email) updatePayload.email = params.email;\r\n if (params.name) updatePayload.name = params.name;\r\n if (params.phone) updatePayload.phone = params.phone;\r\n\r\n const metadataToUpdate: Record<string, string> = {};\r\n if (params.userId) metadataToUpdate.vibez_user_id = params.userId;\r\n const orgId = params.orgId || params.organizationId;\r\n if (orgId) metadataToUpdate.org_id = String(orgId);\r\n if (params.orgName) metadataToUpdate.org_name = String(params.orgName);\r\n const teamId = params.teamId || params.workspaceId;\r\n if (teamId) metadataToUpdate.team_id = String(teamId);\r\n if (params.plan) metadataToUpdate.plan = String(params.plan);\r\n if (params.tier) metadataToUpdate.tier = String(params.tier);\r\n if (params.role) metadataToUpdate.role = String(params.role);\r\n\r\n if (params.metadata) {\r\n for (const [k, v] of Object.entries(params.metadata)) {\r\n if (v !== undefined && v !== null) {\r\n metadataToUpdate[k] = String(v);\r\n }\r\n }\r\n }\r\n\r\n if (Object.keys(metadataToUpdate).length > 0) {\r\n updatePayload.metadata = metadataToUpdate;\r\n }\r\n\r\n return await this.stripe.customers.update(customerId, updatePayload);\r\n }\r\n\r\n /**\r\n * Clears in-memory resolution cache\r\n */\r\n public clearCache(): void {\r\n this.cache.clear();\r\n }\r\n}\r\n\r\n/**\r\n * Factory to create CustomerManager\r\n */\r\nexport function createCustomerManager(options: CustomerManagerOptions = {}): CustomerManager {\r\n return new CustomerManager(options);\r\n}\r\n","interface CacheEntry {\n customerId: string;\n expiresAt: number;\n}\n\n/**\n * In-memory Customer Resolution Cache with TTL\n */\nexport class CustomerCache {\n private cache = new Map<string, CacheEntry>();\n private readonly defaultTtlMs: number;\n\n constructor(defaultTtlMs: number = 1000 * 60 * 60) {\n // Default TTL: 1 hour\n this.defaultTtlMs = defaultTtlMs;\n }\n\n public get(key: string): string | null {\n const entry = this.cache.get(key);\n if (!entry) return null;\n\n if (Date.now() > entry.expiresAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.customerId;\n }\n\n public set(key: string, customerId: string, ttlMs?: number): void {\n const expiresAt = Date.now() + (ttlMs ?? this.defaultTtlMs);\n this.cache.set(key, { customerId, expiresAt });\n }\n\n public delete(key: string): void {\n this.cache.delete(key);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n","import type { CustomerParam, CustomerInfo } from '../types';\r\n\r\nexport interface NormalizedCustomer {\r\n customerId?: string;\r\n customerEmail?: string;\r\n customerObj?: CustomerInfo;\r\n customerMetadata: Record<string, string | number | boolean>;\r\n}\r\n\r\n/**\r\n * Normalizes string or object customer into structured identifiers and metadata\r\n */\r\nexport function normalizeCustomer(customer?: CustomerParam, extraCustomerId?: string): NormalizedCustomer {\r\n if (!customer && !extraCustomerId) {\r\n return {\r\n customerId: undefined,\r\n customerEmail: undefined,\r\n customerObj: undefined,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n if (typeof customer === 'string') {\r\n const isEmail = customer.includes('@');\r\n const customerObj: CustomerInfo = {\r\n id: customer,\r\n email: isEmail ? customer : undefined,\r\n };\r\n return {\r\n customerId: customer,\r\n customerEmail: isEmail ? customer : undefined,\r\n customerObj,\r\n customerMetadata: {},\r\n };\r\n }\r\n\r\n const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : undefined);\r\n const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;\r\n const customerEmail = customerObj?.email;\r\n\r\n const customerMetadata: Record<string, string | number | boolean> = {};\r\n\r\n if (customerObj) {\r\n const orgId = customerObj.orgId || customerObj.organizationId;\r\n if (orgId) customerMetadata.org_id = String(orgId);\r\n\r\n const teamId = customerObj.teamId || customerObj.workspaceId;\r\n if (teamId) customerMetadata.team_id = String(teamId);\r\n\r\n if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);\r\n if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);\r\n if (customerObj.role) customerMetadata.role = String(customerObj.role);\r\n if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);\r\n\r\n if (customerObj.metadata) {\r\n for (const [key, val] of Object.entries(customerObj.metadata)) {\r\n if (val !== null && val !== undefined) {\r\n customerMetadata[key] = val as string | number | boolean;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n customerId,\r\n customerEmail,\r\n customerObj,\r\n customerMetadata,\r\n };\r\n}\r\n"],"mappings":"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","names":["customerObj"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -3,11 +3,11 @@ import { VibezCheckModelOptions, withBilling, createVibezSession } from './ai-sd
|
|
|
3
3
|
export { VibezSession, VibezSessionOptions, WithBillingOptions, createVibezModel, meteredModel } from './ai-sdk/index.mjs';
|
|
4
4
|
import { calculateCost, getModelPricing, registerModelPricing } from './pricing/index.mjs';
|
|
5
5
|
export { CalculateCostParams, MODEL_PRICING_TABLE, calculateUsageCost, normalizeModelKey } from './pricing/index.mjs';
|
|
6
|
-
import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-
|
|
7
|
-
export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, I as InferenceCost,
|
|
8
|
-
import { V as VibezMeter, c as createMeter } from './client
|
|
6
|
+
import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-Mozk4-Mr.mjs';
|
|
7
|
+
export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, d as CustomerInfo, D as DatabaseAdapter, I as InferenceCost, e as InlineRateConfig, K as KnownModel, f as ModelPricingRates, P as PaymentProvider, g as PricingConfig, R as RecordUsageOptions, h as SupportedAnthropicModel, i as SupportedDeepSeekModel, j as SupportedGoogleModel, k as SupportedModel, l as SupportedOpenAIModel, T as TokenUsage, m as ToolMeterOptions, V as VibezCircuitBreakerError } from './types-Mozk4-Mr.mjs';
|
|
8
|
+
import { V as VibezMeter, c as createMeter } from './client-w_hWhQ6g.mjs';
|
|
9
9
|
import { CustomerManager } from './customers/index.mjs';
|
|
10
|
-
export { CustomerCache, CustomerManagerOptions, GetOrCreateCustomerParams, createCustomerManager } from './customers/index.mjs';
|
|
10
|
+
export { CustomerCache, CustomerManagerOptions, GetOrCreateCustomerParams, NormalizedCustomer, createCustomerManager, normalizeCustomer } from './customers/index.mjs';
|
|
11
11
|
import { ApiKeyAuth } from './auth/index.mjs';
|
|
12
12
|
export { ApiKeyRecord, CreateApiKeyParams, VerifyAuthResult, createApiKeyAuth, extractAuthToken } from './auth/index.mjs';
|
|
13
13
|
import { BillingHelper } from './billing/index.mjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import { VibezCheckModelOptions, withBilling, createVibezSession } from './ai-sd
|
|
|
3
3
|
export { VibezSession, VibezSessionOptions, WithBillingOptions, createVibezModel, meteredModel } from './ai-sdk/index.js';
|
|
4
4
|
import { calculateCost, getModelPricing, registerModelPricing } from './pricing/index.js';
|
|
5
5
|
export { CalculateCostParams, MODEL_PRICING_TABLE, calculateUsageCost, normalizeModelKey } from './pricing/index.js';
|
|
6
|
-
import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-
|
|
7
|
-
export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, I as InferenceCost,
|
|
8
|
-
import { V as VibezMeter, c as createMeter } from './client-
|
|
6
|
+
import { M as MeterOptions, S as StreamWrapOptions, C as CustomerParam, U as UsageEvent, a as UsageSummary } from './types-Mozk4-Mr.js';
|
|
7
|
+
export { B as BillingConfig, b as BudgetExceededEvent, c as CircuitBreakerOptions, d as CustomerInfo, D as DatabaseAdapter, I as InferenceCost, e as InlineRateConfig, K as KnownModel, f as ModelPricingRates, P as PaymentProvider, g as PricingConfig, R as RecordUsageOptions, h as SupportedAnthropicModel, i as SupportedDeepSeekModel, j as SupportedGoogleModel, k as SupportedModel, l as SupportedOpenAIModel, T as TokenUsage, m as ToolMeterOptions, V as VibezCircuitBreakerError } from './types-Mozk4-Mr.js';
|
|
8
|
+
import { V as VibezMeter, c as createMeter } from './client-ynfWcHX6.js';
|
|
9
9
|
import { CustomerManager } from './customers/index.js';
|
|
10
|
-
export { CustomerCache, CustomerManagerOptions, GetOrCreateCustomerParams, createCustomerManager } from './customers/index.js';
|
|
10
|
+
export { CustomerCache, CustomerManagerOptions, GetOrCreateCustomerParams, NormalizedCustomer, createCustomerManager, normalizeCustomer } from './customers/index.js';
|
|
11
11
|
import { ApiKeyAuth } from './auth/index.js';
|
|
12
12
|
export { ApiKeyRecord, CreateApiKeyParams, VerifyAuthResult, createApiKeyAuth, extractAuthToken } from './auth/index.js';
|
|
13
13
|
import { BillingHelper } from './billing/index.js';
|