@nehorai/credits 1.0.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/adapters/index.cjs +463 -0
  2. package/dist/adapters/index.cjs.map +1 -0
  3. package/dist/adapters/index.d.cts +66 -0
  4. package/dist/adapters/index.d.ts +66 -3
  5. package/dist/adapters/index.js +435 -1
  6. package/dist/adapters/index.js.map +1 -1
  7. package/dist/auth/index.cjs +96 -0
  8. package/dist/auth/index.cjs.map +1 -0
  9. package/dist/auth/{api-key.d.ts → index.d.cts} +9 -6
  10. package/dist/auth/index.d.ts +37 -5
  11. package/dist/auth/index.js +65 -7
  12. package/dist/auth/index.js.map +1 -1
  13. package/dist/core/index.cjs +522 -0
  14. package/dist/core/index.cjs.map +1 -0
  15. package/dist/core/index.d.cts +119 -0
  16. package/dist/core/index.d.ts +115 -25
  17. package/dist/core/index.js +475 -27
  18. package/dist/core/index.js.map +1 -1
  19. package/dist/{core/deferred.d.ts → deferred-C7rrRfkm.d.cts} +7 -6
  20. package/dist/{core/deferred.js → deferred-C7rrRfkm.d.ts} +23 -29
  21. package/dist/index.cjs +2506 -0
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.cts +437 -0
  24. package/dist/index.d.ts +429 -49
  25. package/dist/index.js +2399 -62
  26. package/dist/index.js.map +1 -1
  27. package/dist/repository/index.cjs +816 -0
  28. package/dist/repository/index.cjs.map +1 -0
  29. package/dist/repository/{memory/index.d.ts → index.d.cts} +35 -5
  30. package/dist/repository/index.d.ts +97 -7
  31. package/dist/repository/index.js +783 -10
  32. package/dist/repository/index.js.map +1 -1
  33. package/dist/sdk/index.cjs +608 -0
  34. package/dist/sdk/index.cjs.map +1 -0
  35. package/dist/sdk/index.d.cts +495 -0
  36. package/dist/sdk/index.d.ts +491 -9
  37. package/dist/sdk/index.js +568 -12
  38. package/dist/sdk/index.js.map +1 -1
  39. package/dist/service/index.cjs +670 -0
  40. package/dist/service/index.cjs.map +1 -0
  41. package/dist/service/{credits-service.d.ts → index.d.cts} +9 -7
  42. package/dist/service/index.d.ts +141 -3
  43. package/dist/service/index.js +641 -1
  44. package/dist/service/index.js.map +1 -1
  45. package/dist/{core/types.d.ts → types-BBxIWHK2.d.cts} +25 -35
  46. package/dist/types-BBxIWHK2.d.ts +277 -0
  47. package/dist/types-D1vdeBcA.d.cts +305 -0
  48. package/dist/{auth/types.d.ts → types-OZU3I5OM.d.cts} +5 -4
  49. package/dist/types-OZU3I5OM.d.ts +32 -0
  50. package/dist/{repository/types.d.ts → types-aJsyv8df.d.ts} +35 -13
  51. package/package.json +14 -13
  52. package/dist/adapters/generic.d.ts +0 -18
  53. package/dist/adapters/generic.d.ts.map +0 -1
  54. package/dist/adapters/generic.js +0 -147
  55. package/dist/adapters/generic.js.map +0 -1
  56. package/dist/adapters/index.d.ts.map +0 -1
  57. package/dist/adapters/types.d.ts +0 -45
  58. package/dist/adapters/types.d.ts.map +0 -1
  59. package/dist/adapters/types.js +0 -8
  60. package/dist/adapters/types.js.map +0 -1
  61. package/dist/auth/api-key.d.ts.map +0 -1
  62. package/dist/auth/api-key.js +0 -94
  63. package/dist/auth/api-key.js.map +0 -1
  64. package/dist/auth/index.d.ts.map +0 -1
  65. package/dist/auth/types.d.ts.map +0 -1
  66. package/dist/auth/types.js +0 -2
  67. package/dist/auth/types.js.map +0 -1
  68. package/dist/config/costs.d.ts +0 -61
  69. package/dist/config/costs.d.ts.map +0 -1
  70. package/dist/config/costs.js +0 -86
  71. package/dist/config/costs.js.map +0 -1
  72. package/dist/config/index.d.ts +0 -165
  73. package/dist/config/index.d.ts.map +0 -1
  74. package/dist/config/index.js +0 -286
  75. package/dist/config/index.js.map +0 -1
  76. package/dist/core/deferred.d.ts.map +0 -1
  77. package/dist/core/deferred.js.map +0 -1
  78. package/dist/core/errors.d.ts +0 -78
  79. package/dist/core/errors.d.ts.map +0 -1
  80. package/dist/core/errors.js +0 -110
  81. package/dist/core/errors.js.map +0 -1
  82. package/dist/core/index.d.ts.map +0 -1
  83. package/dist/core/operations.d.ts +0 -36
  84. package/dist/core/operations.d.ts.map +0 -1
  85. package/dist/core/operations.js +0 -87
  86. package/dist/core/operations.js.map +0 -1
  87. package/dist/core/types.d.ts.map +0 -1
  88. package/dist/core/types.js +0 -93
  89. package/dist/core/types.js.map +0 -1
  90. package/dist/index.d.ts.map +0 -1
  91. package/dist/notifications/index.d.ts +0 -76
  92. package/dist/notifications/index.d.ts.map +0 -1
  93. package/dist/notifications/index.js +0 -182
  94. package/dist/notifications/index.js.map +0 -1
  95. package/dist/repository/index.d.ts.map +0 -1
  96. package/dist/repository/memory/index.d.ts.map +0 -1
  97. package/dist/repository/memory/index.js +0 -518
  98. package/dist/repository/memory/index.js.map +0 -1
  99. package/dist/repository/types.d.ts.map +0 -1
  100. package/dist/repository/types.js +0 -39
  101. package/dist/repository/types.js.map +0 -1
  102. package/dist/repository/utils.d.ts +0 -22
  103. package/dist/repository/utils.d.ts.map +0 -1
  104. package/dist/repository/utils.js +0 -40
  105. package/dist/repository/utils.js.map +0 -1
  106. package/dist/sdk/admin-client.d.ts +0 -146
  107. package/dist/sdk/admin-client.d.ts.map +0 -1
  108. package/dist/sdk/admin-client.js +0 -196
  109. package/dist/sdk/admin-client.js.map +0 -1
  110. package/dist/sdk/client.d.ts +0 -144
  111. package/dist/sdk/client.d.ts.map +0 -1
  112. package/dist/sdk/client.js +0 -247
  113. package/dist/sdk/client.js.map +0 -1
  114. package/dist/sdk/errors.d.ts +0 -91
  115. package/dist/sdk/errors.d.ts.map +0 -1
  116. package/dist/sdk/errors.js +0 -185
  117. package/dist/sdk/errors.js.map +0 -1
  118. package/dist/sdk/index.d.ts.map +0 -1
  119. package/dist/sdk/types.d.ts +0 -110
  120. package/dist/sdk/types.d.ts.map +0 -1
  121. package/dist/sdk/types.js +0 -20
  122. package/dist/sdk/types.js.map +0 -1
  123. package/dist/service/credits-service.d.ts.map +0 -1
  124. package/dist/service/credits-service.js +0 -372
  125. package/dist/service/credits-service.js.map +0 -1
  126. package/dist/service/index.d.ts.map +0 -1
  127. package/dist/utils/error-utils.d.ts +0 -48
  128. package/dist/utils/error-utils.d.ts.map +0 -1
  129. package/dist/utils/error-utils.js +0 -57
  130. package/dist/utils/error-utils.js.map +0 -1
  131. package/dist/utils/index.d.ts +0 -54
  132. package/dist/utils/index.d.ts.map +0 -1
  133. package/dist/utils/index.js +0 -72
  134. package/dist/utils/index.js.map +0 -1
@@ -1,93 +0,0 @@
1
- /**
2
- * Portable credits types - framework and database agnostic
3
- *
4
- * These types use standard JavaScript types (string, Date) instead of
5
- * Firebase-specific types (Timestamp). This makes the credits system
6
- * portable to other environments without Firebase dependencies.
7
- *
8
- * Note: Firestore Timestamp is handled by the credits-firestore adapter.
9
- */
10
- // ==================== Utility Functions ====================
11
- /**
12
- * Calculate available credits from balance, bonus, and reserved amounts.
13
- *
14
- * Available = balance + bonusCredits - reserved
15
- *
16
- * @param balance - Regular monthly credits
17
- * @param bonusCredits - Purchased/admin credits
18
- * @param reserved - Credits locked for in-flight operations
19
- * @returns Available credits for new operations
20
- */
21
- export function calculateAvailableCredits(balance, bonusCredits, reserved) {
22
- return balance + bonusCredits - reserved;
23
- }
24
- /**
25
- * Convert various timestamp formats to ISO string.
26
- *
27
- * Handles:
28
- * - Date objects
29
- * - ISO string (returned as-is)
30
- * - Timestamp-like objects with toDate() method (Firebase)
31
- * - undefined/null (returns current time)
32
- *
33
- * @param value - Value to convert
34
- * @returns ISO 8601 string
35
- */
36
- export function toPortableTimestamp(value) {
37
- if (!value) {
38
- return new Date().toISOString();
39
- }
40
- if (typeof value === "string") {
41
- return value;
42
- }
43
- if (value instanceof Date) {
44
- return value.toISOString();
45
- }
46
- if (typeof value === "object" &&
47
- value !== null &&
48
- "toDate" in value &&
49
- typeof value.toDate === "function") {
50
- return value.toDate().toISOString();
51
- }
52
- return new Date().toISOString();
53
- }
54
- /**
55
- * Convert various timestamp formats to Date object.
56
- *
57
- * Handles:
58
- * - Date objects (returned as-is)
59
- * - ISO string
60
- * - Timestamp-like objects with toDate() method (Firebase)
61
- * - Invalid values (returns current date)
62
- *
63
- * @param value - Value to convert
64
- * @returns Date object
65
- */
66
- export function toDate(value) {
67
- if (value instanceof Date) {
68
- return value;
69
- }
70
- if (typeof value === "string") {
71
- return new Date(value);
72
- }
73
- if (typeof value === "object" &&
74
- value !== null &&
75
- "toDate" in value &&
76
- typeof value.toDate === "function") {
77
- return value.toDate();
78
- }
79
- return new Date();
80
- }
81
- // ==================== Constants ====================
82
- /**
83
- * Constants for credit system configuration
84
- */
85
- export const CREDIT_CONSTANTS = {
86
- /** Grace period in days after subscription expires before downgrade */
87
- SUBSCRIPTION_GRACE_PERIOD_DAYS: 3,
88
- /** Low balance notification threshold */
89
- LOW_BALANCE_THRESHOLD: 10,
90
- /** Cooldown in hours between low balance notifications */
91
- LOW_BALANCE_NOTIFICATION_COOLDOWN_HOURS: 24,
92
- };
93
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8DAA8D;AAE9D;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAe,EACf,YAAoB,EACpB,QAAgB;IAEhB,OAAO,OAAO,GAAG,YAAY,GAAG,QAAQ,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IAC7B,CAAC;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,QAAQ,IAAI,KAAK;QACjB,OAAQ,KAAgC,CAAC,MAAM,KAAK,UAAU,EAC9D,CAAC;QACD,OAAQ,KAAgC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;IAClE,CAAC;IAED,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,QAAQ,IAAI,KAAK;QACjB,OAAQ,KAAgC,CAAC,MAAM,KAAK,UAAU,EAC9D,CAAC;QACD,OAAQ,KAAgC,CAAC,MAAM,EAAE,CAAC;IACpD,CAAC;IAED,OAAO,IAAI,IAAI,EAAE,CAAC;AACpB,CAAC;AAgSD,sDAAsD;AAEtD;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,uEAAuE;IACvE,8BAA8B,EAAE,CAAC;IACjC,yCAAyC;IACzC,qBAAqB,EAAE,EAAE;IACzB,0DAA0D;IAC1D,uCAAuC,EAAE,EAAE;CACnC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAI3B,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EACL,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,8BAA8B,CAAC;AAGtC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,qBAAqB,CAAC;AAGpC,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,kBAAkB,EAClB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,GAChC,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,iBAAiB,EACjB,iBAAiB,IAAI,oBAAoB,EACzC,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,IAAI,oBAAoB,EACzC,oBAAoB,IAAI,uBAAuB,EAC/C,WAAW,EACX,gBAAgB,EAChB,gBAAgB,IAAI,mBAAmB,GACxC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,IAAI,2BAA2B,EACvD,wBAAwB,IAAI,2BAA2B,EACvD,uBAAuB,IAAI,0BAA0B,EACrD,eAAe,EACf,WAAW,EACX,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,sBAAsB,EACtB,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC"}
@@ -1,76 +0,0 @@
1
- /**
2
- * Notification event types
3
- */
4
- export type CreditNotificationEvent = {
5
- type: "low_balance";
6
- userId: string;
7
- balance: number;
8
- threshold: number;
9
- } | {
10
- type: "balance_depleted";
11
- userId: string;
12
- } | {
13
- type: "subscription_expiring";
14
- userId: string;
15
- expiresAt: Date;
16
- daysRemaining: number;
17
- } | {
18
- type: "subscription_expired";
19
- userId: string;
20
- wasDowngraded: boolean;
21
- };
22
- /**
23
- * Notification handler interface
24
- * Implementations can send emails, push notifications, etc.
25
- */
26
- export interface ICreditNotificationHandler {
27
- /**
28
- * Handle a notification event
29
- * @param event - The notification event
30
- */
31
- handleNotification(event: CreditNotificationEvent): Promise<void>;
32
- }
33
- /**
34
- * Register a notification handler
35
- */
36
- export declare function registerNotificationHandler(handler: ICreditNotificationHandler): void;
37
- /**
38
- * Clear all notification handlers (for testing)
39
- */
40
- export declare function clearNotificationHandlers(): void;
41
- /**
42
- * Clear cooldown state (for testing)
43
- */
44
- export declare function clearCooldownState(): void;
45
- /**
46
- * Check and trigger low balance notification if needed
47
- * Call this after commit operations
48
- *
49
- * @param userId - User ID
50
- * @param newBalance - Balance after the operation
51
- * @param threshold - Custom threshold (defaults to 10)
52
- */
53
- export declare function checkAndNotifyLowBalance(userId: string, newBalance: number, threshold?: 10): Promise<void>;
54
- /**
55
- * Trigger subscription expiring notification
56
- *
57
- * @param userId - User ID
58
- * @param expiresAt - When subscription expires
59
- * @param daysRemaining - Days until expiry
60
- */
61
- export declare function notifySubscriptionExpiring(userId: string, expiresAt: Date, daysRemaining: number): Promise<void>;
62
- /**
63
- * Trigger subscription expired notification
64
- *
65
- * @param userId - User ID
66
- * @param wasDowngraded - Whether the user was downgraded to free tier
67
- */
68
- export declare function notifySubscriptionExpired(userId: string, wasDowngraded: boolean): Promise<void>;
69
- /**
70
- * Console notification handler for development/testing
71
- * Logs notifications to console
72
- */
73
- export declare class ConsoleNotificationHandler implements ICreditNotificationHandler {
74
- handleNotification(event: CreditNotificationEvent): Promise<void>;
75
- }
76
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IACE,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,uBAAuB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEN;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAyFD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,0BAA0B,GAClC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAyBD;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,SAAS,KAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,EACf,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,0BAA0B;IACrE,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BxE"}
@@ -1,182 +0,0 @@
1
- import { CREDIT_CONSTANTS } from "../core/types.js";
2
- /**
3
- * In-memory cooldown tracker
4
- * In production, this should be stored in a persistent store
5
- */
6
- const cooldownState = new Map();
7
- /**
8
- * Default notification threshold for low balance
9
- */
10
- const LOW_BALANCE_THRESHOLD = CREDIT_CONSTANTS.LOW_BALANCE_THRESHOLD;
11
- /**
12
- * Cooldown period in milliseconds (24 hours)
13
- */
14
- const NOTIFICATION_COOLDOWN_MS = CREDIT_CONSTANTS.LOW_BALANCE_NOTIFICATION_COOLDOWN_HOURS * 60 * 60 * 1000;
15
- /**
16
- * Check if a notification is allowed (not in cooldown)
17
- */
18
- function isNotificationAllowed(userId, eventType) {
19
- const state = cooldownState.get(userId);
20
- if (!state)
21
- return true;
22
- const now = Date.now();
23
- let lastNotification;
24
- switch (eventType) {
25
- case "lowBalance":
26
- lastNotification = state.lastLowBalanceNotification;
27
- break;
28
- case "depleted":
29
- lastNotification = state.lastDepletedNotification;
30
- break;
31
- case "expiring":
32
- lastNotification = state.lastExpiringNotification;
33
- break;
34
- }
35
- if (!lastNotification)
36
- return true;
37
- return now - lastNotification.getTime() > NOTIFICATION_COOLDOWN_MS;
38
- }
39
- /**
40
- * Record that a notification was sent
41
- */
42
- function recordNotification(userId, eventType) {
43
- const state = cooldownState.get(userId) || {};
44
- const now = new Date();
45
- switch (eventType) {
46
- case "lowBalance":
47
- state.lastLowBalanceNotification = now;
48
- break;
49
- case "depleted":
50
- state.lastDepletedNotification = now;
51
- break;
52
- case "expiring":
53
- state.lastExpiringNotification = now;
54
- break;
55
- }
56
- cooldownState.set(userId, state);
57
- }
58
- /**
59
- * Default notification handlers registry
60
- * Handlers can be registered at application startup
61
- */
62
- const notificationHandlers = [];
63
- /**
64
- * Register a notification handler
65
- */
66
- export function registerNotificationHandler(handler) {
67
- notificationHandlers.push(handler);
68
- }
69
- /**
70
- * Clear all notification handlers (for testing)
71
- */
72
- export function clearNotificationHandlers() {
73
- notificationHandlers.length = 0;
74
- }
75
- /**
76
- * Clear cooldown state (for testing)
77
- */
78
- export function clearCooldownState() {
79
- cooldownState.clear();
80
- }
81
- /**
82
- * Dispatch a notification event to all handlers
83
- * Runs asynchronously without blocking
84
- */
85
- async function dispatchNotification(event) {
86
- if (notificationHandlers.length === 0) {
87
- // No handlers registered - log for debugging
88
- console.debug(`[Credits] No notification handlers registered for: ${event.type}`);
89
- return;
90
- }
91
- // Run handlers in parallel
92
- await Promise.allSettled(notificationHandlers.map((handler) => handler.handleNotification(event).catch((error) => {
93
- console.error(`[Credits] Notification handler error:`, error);
94
- })));
95
- }
96
- /**
97
- * Check and trigger low balance notification if needed
98
- * Call this after commit operations
99
- *
100
- * @param userId - User ID
101
- * @param newBalance - Balance after the operation
102
- * @param threshold - Custom threshold (defaults to 10)
103
- */
104
- export async function checkAndNotifyLowBalance(userId, newBalance, threshold = LOW_BALANCE_THRESHOLD) {
105
- // Check if balance is depleted
106
- if (newBalance <= 0 && isNotificationAllowed(userId, "depleted")) {
107
- recordNotification(userId, "depleted");
108
- await dispatchNotification({
109
- type: "balance_depleted",
110
- userId,
111
- });
112
- return; // Don't also send low balance notification
113
- }
114
- // Check if balance is below threshold
115
- if (newBalance > 0 && newBalance <= threshold && isNotificationAllowed(userId, "lowBalance")) {
116
- recordNotification(userId, "lowBalance");
117
- await dispatchNotification({
118
- type: "low_balance",
119
- userId,
120
- balance: newBalance,
121
- threshold,
122
- });
123
- }
124
- }
125
- /**
126
- * Trigger subscription expiring notification
127
- *
128
- * @param userId - User ID
129
- * @param expiresAt - When subscription expires
130
- * @param daysRemaining - Days until expiry
131
- */
132
- export async function notifySubscriptionExpiring(userId, expiresAt, daysRemaining) {
133
- if (!isNotificationAllowed(userId, "expiring")) {
134
- return;
135
- }
136
- recordNotification(userId, "expiring");
137
- await dispatchNotification({
138
- type: "subscription_expiring",
139
- userId,
140
- expiresAt,
141
- daysRemaining,
142
- });
143
- }
144
- /**
145
- * Trigger subscription expired notification
146
- *
147
- * @param userId - User ID
148
- * @param wasDowngraded - Whether the user was downgraded to free tier
149
- */
150
- export async function notifySubscriptionExpired(userId, wasDowngraded) {
151
- await dispatchNotification({
152
- type: "subscription_expired",
153
- userId,
154
- wasDowngraded,
155
- });
156
- }
157
- /**
158
- * Console notification handler for development/testing
159
- * Logs notifications to console
160
- */
161
- export class ConsoleNotificationHandler {
162
- async handleNotification(event) {
163
- switch (event.type) {
164
- case "low_balance":
165
- console.log(`[Credits Notification] Low balance alert for user ${event.userId}: ` +
166
- `${event.balance} credits remaining (threshold: ${event.threshold})`);
167
- break;
168
- case "balance_depleted":
169
- console.log(`[Credits Notification] Balance depleted for user ${event.userId}`);
170
- break;
171
- case "subscription_expiring":
172
- console.log(`[Credits Notification] Subscription expiring for user ${event.userId}: ` +
173
- `${event.daysRemaining} days remaining`);
174
- break;
175
- case "subscription_expired":
176
- console.log(`[Credits Notification] Subscription expired for user ${event.userId}: ` +
177
- `downgraded=${event.wasDowngraded}`);
178
- break;
179
- }
180
- }
181
- }
182
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repository/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGrE,OAAO,EACL,wBAAwB,EACxB,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/repository/memory/index.ts"],"names":[],"mappings":"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"}