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.
Files changed (38) hide show
  1. package/README.md +273 -203
  2. package/dist/ai-sdk/index.d.mts +6 -4
  3. package/dist/ai-sdk/index.d.ts +6 -4
  4. package/dist/ai-sdk/index.js +184 -22
  5. package/dist/ai-sdk/index.js.map +1 -1
  6. package/dist/ai-sdk/index.mjs +184 -22
  7. package/dist/ai-sdk/index.mjs.map +1 -1
  8. package/dist/cli/index.js +316 -17
  9. package/dist/cli/index.js.map +1 -1
  10. package/dist/cli/index.mjs +316 -17
  11. package/dist/cli/index.mjs.map +1 -1
  12. package/dist/{client-kJN_Znan.d.ts → client-w_hWhQ6g.d.mts} +4 -2
  13. package/dist/{client--iq93FQg.d.mts → client-ynfWcHX6.d.ts} +4 -2
  14. package/dist/customers/index.d.mts +30 -4
  15. package/dist/customers/index.d.ts +30 -4
  16. package/dist/customers/index.js +108 -8
  17. package/dist/customers/index.js.map +1 -1
  18. package/dist/customers/index.mjs +106 -7
  19. package/dist/customers/index.mjs.map +1 -1
  20. package/dist/index.d.mts +4 -4
  21. package/dist/index.d.ts +4 -4
  22. package/dist/index.js +238 -28
  23. package/dist/index.js.map +1 -1
  24. package/dist/index.mjs +237 -28
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/meter/index.d.mts +2 -2
  27. package/dist/meter/index.d.ts +2 -2
  28. package/dist/meter/index.js +95 -16
  29. package/dist/meter/index.js.map +1 -1
  30. package/dist/meter/index.mjs +95 -16
  31. package/dist/meter/index.mjs.map +1 -1
  32. package/dist/pricing/index.d.mts +1 -1
  33. package/dist/pricing/index.d.ts +1 -1
  34. package/dist/react/index.d.mts +1 -1
  35. package/dist/react/index.d.ts +1 -1
  36. package/dist/{types-Zbzxg-Ka.d.mts → types-Mozk4-Mr.d.mts} +70 -12
  37. package/dist/{types-Zbzxg-Ka.d.ts → types-Mozk4-Mr.d.ts} +70 -12
  38. package/package.json +161 -153
package/dist/index.js CHANGED
@@ -58,6 +58,7 @@ __export(src_exports, {
58
58
  getModelPricing: () => getModelPricing,
59
59
  inspectOpenAIStreamChunk: () => inspectOpenAIStreamChunk,
60
60
  meteredModel: () => meteredModel,
61
+ normalizeCustomer: () => normalizeCustomer,
61
62
  normalizeModelKey: () => normalizeModelKey,
62
63
  registerModelPricing: () => registerModelPricing,
63
64
  trackTokens: () => trackTokens,
@@ -682,6 +683,58 @@ function calculateUsageCost(model, usage, optionsOrMarkup) {
682
683
  });
683
684
  }
684
685
 
686
+ // src/customers/helpers.ts
687
+ function normalizeCustomer(customer, extraCustomerId) {
688
+ if (!customer && !extraCustomerId) {
689
+ return {
690
+ customerId: void 0,
691
+ customerEmail: void 0,
692
+ customerObj: void 0,
693
+ customerMetadata: {}
694
+ };
695
+ }
696
+ if (typeof customer === "string") {
697
+ const isEmail = customer.includes("@");
698
+ const customerObj2 = {
699
+ id: customer,
700
+ email: isEmail ? customer : void 0
701
+ };
702
+ return {
703
+ customerId: customer,
704
+ customerEmail: isEmail ? customer : void 0,
705
+ customerObj: customerObj2,
706
+ customerMetadata: {}
707
+ };
708
+ }
709
+ const customerObj = customer || (extraCustomerId ? { id: extraCustomerId } : void 0);
710
+ const customerId = customerObj?.id || customerObj?.userId || extraCustomerId;
711
+ const customerEmail = customerObj?.email;
712
+ const customerMetadata = {};
713
+ if (customerObj) {
714
+ const orgId = customerObj.orgId || customerObj.organizationId;
715
+ if (orgId) customerMetadata.org_id = String(orgId);
716
+ const teamId = customerObj.teamId || customerObj.workspaceId;
717
+ if (teamId) customerMetadata.team_id = String(teamId);
718
+ if (customerObj.plan) customerMetadata.plan = String(customerObj.plan);
719
+ if (customerObj.tier) customerMetadata.tier = String(customerObj.tier);
720
+ if (customerObj.role) customerMetadata.role = String(customerObj.role);
721
+ if (customerObj.orgName) customerMetadata.org_name = String(customerObj.orgName);
722
+ if (customerObj.metadata) {
723
+ for (const [key, val] of Object.entries(customerObj.metadata)) {
724
+ if (val !== null && val !== void 0) {
725
+ customerMetadata[key] = val;
726
+ }
727
+ }
728
+ }
729
+ }
730
+ return {
731
+ customerId,
732
+ customerEmail,
733
+ customerObj,
734
+ customerMetadata
735
+ };
736
+ }
737
+
685
738
  // src/meter/stream.ts
686
739
  function wrapOpenAIStream(stream, options, onComplete) {
687
740
  let detectedModel = options.model || "gpt-4o";
@@ -702,15 +755,20 @@ function wrapOpenAIStream(stream, options, onComplete) {
702
755
  } finally {
703
756
  if (finalUsage) {
704
757
  const cost = calculateUsageCost(detectedModel, finalUsage);
705
- const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
758
+ const normalized = normalizeCustomer(options.customer, options.customerId);
706
759
  const event = {
707
760
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
708
761
  model: detectedModel,
709
762
  provider: "openai",
710
763
  usage: finalUsage,
711
764
  cost,
712
- customerId,
713
- metadata: options.metadata
765
+ customerId: normalized.customerId,
766
+ customerEmail: normalized.customerEmail,
767
+ customer: normalized.customerObj,
768
+ metadata: {
769
+ ...normalized.customerMetadata,
770
+ ...options.metadata
771
+ }
714
772
  };
715
773
  onComplete(event);
716
774
  if (options.onUsage) {
@@ -735,15 +793,20 @@ function wrapAnthropicStream(stream, options, onComplete) {
735
793
  const extracted = accumulator.getUsage();
736
794
  const model = options.model || extracted.model;
737
795
  const cost = calculateUsageCost(model, extracted.usage);
738
- const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
796
+ const normalized = normalizeCustomer(options.customer, options.customerId);
739
797
  const usageEvent = {
740
798
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
741
799
  model,
742
800
  provider: "anthropic",
743
801
  usage: extracted.usage,
744
802
  cost,
745
- customerId,
746
- metadata: options.metadata
803
+ customerId: normalized.customerId,
804
+ customerEmail: normalized.customerEmail,
805
+ customer: normalized.customerObj,
806
+ metadata: {
807
+ ...normalized.customerMetadata,
808
+ ...options.metadata
809
+ }
747
810
  };
748
811
  onComplete(usageEvent);
749
812
  if (options.onUsage) {
@@ -772,15 +835,20 @@ function wrapGeminiStream(result, options, onComplete) {
772
835
  const extracted = extractGeminiResponseUsage(lastChunkWithUsage, model);
773
836
  if (extracted) {
774
837
  const cost = calculateUsageCost(extracted.model, extracted.usage);
775
- const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
838
+ const normalized = normalizeCustomer(options.customer, options.customerId);
776
839
  const event = {
777
840
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
778
841
  model: extracted.model,
779
842
  provider: "google",
780
843
  usage: extracted.usage,
781
844
  cost,
782
- customerId,
783
- metadata: options.metadata
845
+ customerId: normalized.customerId,
846
+ customerEmail: normalized.customerEmail,
847
+ customer: normalized.customerObj,
848
+ metadata: {
849
+ ...normalized.customerMetadata,
850
+ ...options.metadata
851
+ }
784
852
  };
785
853
  onComplete(event);
786
854
  if (options.onUsage) {
@@ -823,7 +891,7 @@ var VibezMeter = class {
823
891
  this.stripeClient = new import_stripe.default(key, {
824
892
  appInfo: {
825
893
  name: "vibezcheck",
826
- version: "0.1.0",
894
+ version: "0.4.2",
827
895
  url: "https://vibezcheck.xyz"
828
896
  }
829
897
  });
@@ -843,15 +911,21 @@ var VibezMeter = class {
843
911
  }
844
912
  const model = options.model || extracted.model;
845
913
  const cost = calculateUsageCost(model, extracted.usage, this.markupMultiplier);
846
- const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
914
+ const normalized = normalizeCustomer(options.customer, options.customerId);
915
+ const mergedMeta = {
916
+ ...normalized.customerMetadata,
917
+ ...options.metadata
918
+ };
847
919
  const event = {
848
920
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
849
921
  model,
850
922
  provider: extracted.provider,
851
923
  usage: extracted.usage,
852
924
  cost,
853
- customerId,
854
- metadata: options.metadata
925
+ customerId: normalized.customerId,
926
+ customerEmail: normalized.customerEmail,
927
+ customer: normalized.customerObj,
928
+ metadata: mergedMeta
855
929
  };
856
930
  this.batcher.enqueue(event);
857
931
  return event;
@@ -881,15 +955,21 @@ var VibezMeter = class {
881
955
  cachedTokens
882
956
  };
883
957
  const cost = calculateUsageCost(options.model, usage, this.markupMultiplier);
884
- const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
958
+ const normalized = normalizeCustomer(options.customer, options.customerId);
959
+ const mergedMeta = {
960
+ ...normalized.customerMetadata,
961
+ ...options.metadata
962
+ };
885
963
  const event = {
886
964
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
887
965
  model: options.model,
888
966
  provider: options.provider || "custom",
889
967
  usage,
890
968
  cost,
891
- customerId,
892
- metadata: options.metadata
969
+ customerId: normalized.customerId,
970
+ customerEmail: normalized.customerEmail,
971
+ customer: normalized.customerObj,
972
+ metadata: mergedMeta
893
973
  };
894
974
  this.batcher.enqueue(event);
895
975
  return event;
@@ -936,7 +1016,11 @@ function withBilling(model, options = {}) {
936
1016
  apiKey: options.stripeApiKey,
937
1017
  eventName: options.eventName
938
1018
  });
939
- const customerId = typeof options.customer === "string" ? options.customer : options.customer?.id || options.customerId;
1019
+ const normalized = normalizeCustomer(options.customer, options.customerId);
1020
+ const customerId = normalized.customerId;
1021
+ const customerEmail = normalized.customerEmail;
1022
+ const customerObj = normalized.customerObj;
1023
+ const customerMetadata = normalized.customerMetadata;
940
1024
  const modelId = model.modelId || "unknown-model";
941
1025
  const provider = model.provider?.replace(/^@ai-sdk\//, "") || "ai-sdk";
942
1026
  const maxCostPerCall = options.maxCostPerCallUSD !== void 0 ? options.maxCostPerCallUSD : 0.5;
@@ -1005,6 +1089,12 @@ function withBilling(model, options = {}) {
1005
1089
  throw new VibezCircuitBreakerError(budgetEvent);
1006
1090
  }
1007
1091
  }
1092
+ const mergedMetadata = {
1093
+ ...customerMetadata,
1094
+ ...options.metadata,
1095
+ ...extraMeta,
1096
+ billingMode: options.billing?.mode || "postpaid"
1097
+ };
1008
1098
  const event = {
1009
1099
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1010
1100
  model: modelId,
@@ -1012,11 +1102,9 @@ function withBilling(model, options = {}) {
1012
1102
  usage,
1013
1103
  cost,
1014
1104
  customerId,
1015
- metadata: {
1016
- ...options.metadata,
1017
- ...extraMeta,
1018
- billingMode: options.billing?.mode || "postpaid"
1019
- }
1105
+ customerEmail,
1106
+ customer: customerObj,
1107
+ metadata: mergedMetadata
1020
1108
  };
1021
1109
  meter.recordUsage({
1022
1110
  model: modelId,
@@ -1026,11 +1114,84 @@ function withBilling(model, options = {}) {
1026
1114
  reasoningTokens: usage.reasoningTokens,
1027
1115
  cachedTokens: usage.cachedTokens,
1028
1116
  customerId,
1117
+ customer: customerObj,
1029
1118
  metadata: event.metadata
1030
1119
  });
1031
1120
  if (options.onUsage) {
1032
1121
  options.onUsage(event);
1033
1122
  }
1123
+ if (options.database) {
1124
+ const dbTarget = options.database;
1125
+ const executeDbWrite = async () => {
1126
+ try {
1127
+ const supabaseClient = typeof dbTarget === "object" && dbTarget !== null && typeof dbTarget.from === "function" ? dbTarget : typeof dbTarget === "object" && dbTarget !== null && typeof dbTarget.client?.from === "function" ? dbTarget.client : null;
1128
+ if (supabaseClient) {
1129
+ const tableName = dbTarget?.table || "vibez_usage";
1130
+ await supabaseClient.from(tableName).insert({
1131
+ customer_id: customerId,
1132
+ user_id: customerObj?.userId || customerId,
1133
+ model: modelId,
1134
+ input_tokens: usage.inputTokens,
1135
+ output_tokens: usage.outputTokens,
1136
+ total_tokens: usage.totalTokens,
1137
+ cached_tokens: usage.cachedTokens,
1138
+ reasoning_tokens: usage.reasoningTokens,
1139
+ cost_usd: cost.totalUSD,
1140
+ created_at: event.timestamp,
1141
+ metadata: event.metadata
1142
+ });
1143
+ return;
1144
+ }
1145
+ if (typeof dbTarget === "object" && dbTarget !== null && typeof dbTarget.save === "function") {
1146
+ await dbTarget.save(event);
1147
+ return;
1148
+ }
1149
+ if (typeof dbTarget === "function") {
1150
+ await dbTarget(event);
1151
+ return;
1152
+ }
1153
+ } catch (err) {
1154
+ console.warn(`[vibezcheck] Database record failed safely:`, err?.message || err);
1155
+ }
1156
+ };
1157
+ if (typeof globalThis !== "undefined" && typeof globalThis.after === "function") {
1158
+ globalThis.after(() => executeDbWrite());
1159
+ } else {
1160
+ executeDbWrite().catch(() => {
1161
+ });
1162
+ }
1163
+ }
1164
+ if (options.billing?.charge && typeof options.billing.charge === "function") {
1165
+ const chargeFn = options.billing.charge;
1166
+ const executeCharge = async () => {
1167
+ try {
1168
+ await chargeFn(cost.totalUSD, event);
1169
+ } catch (err) {
1170
+ console.warn(`[vibezcheck] Custom charge handler failed safely:`, err?.message || err);
1171
+ }
1172
+ };
1173
+ if (typeof globalThis !== "undefined" && typeof globalThis.after === "function") {
1174
+ globalThis.after(() => executeCharge());
1175
+ } else {
1176
+ executeCharge().catch(() => {
1177
+ });
1178
+ }
1179
+ } else if (options.billing?.provider && typeof options.billing.provider === "object" && typeof options.billing.provider.charge === "function") {
1180
+ const providerCharge = options.billing.provider.charge;
1181
+ const executeCharge = async () => {
1182
+ try {
1183
+ await providerCharge(cost.totalUSD, event);
1184
+ } catch (err) {
1185
+ console.warn(`[vibezcheck] Payment provider charge failed safely:`, err?.message || err);
1186
+ }
1187
+ };
1188
+ if (typeof globalThis !== "undefined" && typeof globalThis.after === "function") {
1189
+ globalThis.after(() => executeCharge());
1190
+ } else {
1191
+ executeCharge().catch(() => {
1192
+ });
1193
+ }
1194
+ }
1034
1195
  scheduleFlush();
1035
1196
  };
1036
1197
  const handler = {
@@ -1078,6 +1239,8 @@ function withBilling(model, options = {}) {
1078
1239
  controller.enqueue(chunk);
1079
1240
  if (chunk.type === "text-delta" && chunk.textDelta) {
1080
1241
  accumulatedChars += chunk.textDelta.length;
1242
+ } else if (chunk.type === "reasoning" && (chunk.textDelta || chunk.reasoning)) {
1243
+ accumulatedChars += (chunk.textDelta || chunk.reasoning || "").length;
1081
1244
  }
1082
1245
  if (chunk.type === "finish" && chunk.usage) {
1083
1246
  streamCompleted = true;
@@ -1276,7 +1439,7 @@ var CustomerManager = class {
1276
1439
  this.cache = new CustomerCache(options.cacheTtlMs);
1277
1440
  }
1278
1441
  /**
1279
- * Retrieves existing Stripe Customer or automatically provisions a new one
1442
+ * Retrieves existing Stripe Customer or automatically provisions a new one with full metadata
1280
1443
  */
1281
1444
  async getOrCreate(params) {
1282
1445
  const cacheKey = params.userId || params.email;
@@ -1317,20 +1480,66 @@ var CustomerManager = class {
1317
1480
  return { id: customer.id, isNew: false, customer };
1318
1481
  }
1319
1482
  }
1483
+ const orgId = params.orgId || params.organizationId;
1484
+ const teamId = params.teamId || params.workspaceId;
1485
+ const stripeMetadata = {
1486
+ vibez_user_id: params.userId || "",
1487
+ created_by: "vibezcheck"
1488
+ };
1489
+ if (orgId) stripeMetadata.org_id = String(orgId);
1490
+ if (params.orgName) stripeMetadata.org_name = String(params.orgName);
1491
+ if (teamId) stripeMetadata.team_id = String(teamId);
1492
+ if (params.plan) stripeMetadata.plan = String(params.plan);
1493
+ if (params.tier) stripeMetadata.tier = String(params.tier);
1494
+ if (params.role) stripeMetadata.role = String(params.role);
1495
+ if (params.metadata) {
1496
+ for (const [k, v] of Object.entries(params.metadata)) {
1497
+ if (v !== void 0 && v !== null) {
1498
+ stripeMetadata[k] = String(v);
1499
+ }
1500
+ }
1501
+ }
1320
1502
  const newCustomer = await this.stripe.customers.create({
1321
1503
  email: params.email,
1322
1504
  name: params.name,
1323
- metadata: {
1324
- vibez_user_id: params.userId,
1325
- created_by: "vibezcheck",
1326
- ...params.metadata || {}
1327
- }
1505
+ phone: params.phone,
1506
+ metadata: stripeMetadata
1328
1507
  });
1329
1508
  if (cacheKey) this.cache.set(cacheKey, newCustomer.id);
1330
1509
  if (params.userId) this.cache.set(params.userId, newCustomer.id);
1331
1510
  if (params.email) this.cache.set(params.email, newCustomer.id);
1332
1511
  return { id: newCustomer.id, isNew: true, customer: newCustomer };
1333
1512
  }
1513
+ /**
1514
+ * Updates an existing Stripe Customer's information and metadata
1515
+ */
1516
+ async updateCustomer(customerId, params) {
1517
+ const updatePayload = {};
1518
+ if (params.email) updatePayload.email = params.email;
1519
+ if (params.name) updatePayload.name = params.name;
1520
+ if (params.phone) updatePayload.phone = params.phone;
1521
+ const metadataToUpdate = {};
1522
+ if (params.userId) metadataToUpdate.vibez_user_id = params.userId;
1523
+ const orgId = params.orgId || params.organizationId;
1524
+ if (orgId) metadataToUpdate.org_id = String(orgId);
1525
+ if (params.orgName) metadataToUpdate.org_name = String(params.orgName);
1526
+ const teamId = params.teamId || params.workspaceId;
1527
+ if (teamId) metadataToUpdate.team_id = String(teamId);
1528
+ if (params.plan) metadataToUpdate.plan = String(params.plan);
1529
+ if (params.tier) metadataToUpdate.tier = String(params.tier);
1530
+ if (params.role) metadataToUpdate.role = String(params.role);
1531
+ if (params.metadata) {
1532
+ for (const [k, v] of Object.entries(params.metadata)) {
1533
+ if (v !== void 0 && v !== null) {
1534
+ metadataToUpdate[k] = String(v);
1535
+ }
1536
+ }
1537
+ }
1538
+ if (Object.keys(metadataToUpdate).length > 0) {
1539
+ updatePayload.metadata = metadataToUpdate;
1540
+ }
1541
+ return await this.stripe.customers.update(customerId, updatePayload);
1542
+ }
1334
1543
  /**
1335
1544
  * Clears in-memory resolution cache
1336
1545
  */
@@ -1636,6 +1845,7 @@ var vibes = vibez;
1636
1845
  getModelPricing,
1637
1846
  inspectOpenAIStreamChunk,
1638
1847
  meteredModel,
1848
+ normalizeCustomer,
1639
1849
  normalizeModelKey,
1640
1850
  registerModelPricing,
1641
1851
  trackTokens,