@sakeetech/viva-payments-core 0.2.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.
Files changed (203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +413 -0
  3. package/dist/auth/http.d.ts +44 -0
  4. package/dist/auth/http.d.ts.map +1 -0
  5. package/dist/auth/http.js +80 -0
  6. package/dist/auth/http.js.map +1 -0
  7. package/dist/auth/index.d.ts +19 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +18 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/auth/oauth2-strategy.d.ts +117 -0
  12. package/dist/auth/oauth2-strategy.d.ts.map +1 -0
  13. package/dist/auth/oauth2-strategy.js +217 -0
  14. package/dist/auth/oauth2-strategy.js.map +1 -0
  15. package/dist/auth/reseller-strategy.d.ts +65 -0
  16. package/dist/auth/reseller-strategy.d.ts.map +1 -0
  17. package/dist/auth/reseller-strategy.js +68 -0
  18. package/dist/auth/reseller-strategy.js.map +1 -0
  19. package/dist/auth/single-flight.d.ts +81 -0
  20. package/dist/auth/single-flight.d.ts.map +1 -0
  21. package/dist/auth/single-flight.js +160 -0
  22. package/dist/auth/single-flight.js.map +1 -0
  23. package/dist/auth/token-cache.d.ts +50 -0
  24. package/dist/auth/token-cache.d.ts.map +1 -0
  25. package/dist/auth/token-cache.js +59 -0
  26. package/dist/auth/token-cache.js.map +1 -0
  27. package/dist/errors/api-error.d.ts +15 -0
  28. package/dist/errors/api-error.d.ts.map +1 -0
  29. package/dist/errors/api-error.js +18 -0
  30. package/dist/errors/api-error.js.map +1 -0
  31. package/dist/errors/auth-error.d.ts +14 -0
  32. package/dist/errors/auth-error.d.ts.map +1 -0
  33. package/dist/errors/auth-error.js +17 -0
  34. package/dist/errors/auth-error.js.map +1 -0
  35. package/dist/errors/base.d.ts +59 -0
  36. package/dist/errors/base.d.ts.map +1 -0
  37. package/dist/errors/base.js +51 -0
  38. package/dist/errors/base.js.map +1 -0
  39. package/dist/errors/index.d.ts +18 -0
  40. package/dist/errors/index.d.ts.map +1 -0
  41. package/dist/errors/index.js +16 -0
  42. package/dist/errors/index.js.map +1 -0
  43. package/dist/errors/mode-mismatch-error.d.ts +19 -0
  44. package/dist/errors/mode-mismatch-error.d.ts.map +1 -0
  45. package/dist/errors/mode-mismatch-error.js +22 -0
  46. package/dist/errors/mode-mismatch-error.js.map +1 -0
  47. package/dist/errors/rate-limit-error.d.ts +20 -0
  48. package/dist/errors/rate-limit-error.d.ts.map +1 -0
  49. package/dist/errors/rate-limit-error.js +20 -0
  50. package/dist/errors/rate-limit-error.js.map +1 -0
  51. package/dist/errors/validation-error.d.ts +14 -0
  52. package/dist/errors/validation-error.d.ts.map +1 -0
  53. package/dist/errors/validation-error.js +17 -0
  54. package/dist/errors/validation-error.js.map +1 -0
  55. package/dist/errors/webhook-error.d.ts +14 -0
  56. package/dist/errors/webhook-error.d.ts.map +1 -0
  57. package/dist/errors/webhook-error.js +17 -0
  58. package/dist/errors/webhook-error.js.map +1 -0
  59. package/dist/index.d.ts +15 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +15 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/isv/accounts.d.ts +38 -0
  64. package/dist/isv/accounts.d.ts.map +1 -0
  65. package/dist/isv/accounts.js +60 -0
  66. package/dist/isv/accounts.js.map +1 -0
  67. package/dist/isv/client.d.ts +187 -0
  68. package/dist/isv/client.d.ts.map +1 -0
  69. package/dist/isv/client.js +465 -0
  70. package/dist/isv/client.js.map +1 -0
  71. package/dist/isv/index.d.ts +52 -0
  72. package/dist/isv/index.d.ts.map +1 -0
  73. package/dist/isv/index.js +53 -0
  74. package/dist/isv/index.js.map +1 -0
  75. package/dist/isv/legacy-basic-client.d.ts +122 -0
  76. package/dist/isv/legacy-basic-client.d.ts.map +1 -0
  77. package/dist/isv/legacy-basic-client.js +281 -0
  78. package/dist/isv/legacy-basic-client.js.map +1 -0
  79. package/dist/isv/payments.d.ts +199 -0
  80. package/dist/isv/payments.d.ts.map +1 -0
  81. package/dist/isv/payments.js +385 -0
  82. package/dist/isv/payments.js.map +1 -0
  83. package/dist/isv/sources.d.ts +80 -0
  84. package/dist/isv/sources.d.ts.map +1 -0
  85. package/dist/isv/sources.js +112 -0
  86. package/dist/isv/sources.js.map +1 -0
  87. package/dist/isv/webhooks-api.d.ts +48 -0
  88. package/dist/isv/webhooks-api.d.ts.map +1 -0
  89. package/dist/isv/webhooks-api.js +66 -0
  90. package/dist/isv/webhooks-api.js.map +1 -0
  91. package/dist/legacy/client.d.ts +199 -0
  92. package/dist/legacy/client.d.ts.map +1 -0
  93. package/dist/legacy/client.js +351 -0
  94. package/dist/legacy/client.js.map +1 -0
  95. package/dist/legacy/index.d.ts +15 -0
  96. package/dist/legacy/index.d.ts.map +1 -0
  97. package/dist/legacy/index.js +14 -0
  98. package/dist/legacy/index.js.map +1 -0
  99. package/dist/observability/context.d.ts +30 -0
  100. package/dist/observability/context.d.ts.map +1 -0
  101. package/dist/observability/context.js +40 -0
  102. package/dist/observability/context.js.map +1 -0
  103. package/dist/observability/index.d.ts +15 -0
  104. package/dist/observability/index.d.ts.map +1 -0
  105. package/dist/observability/index.js +11 -0
  106. package/dist/observability/index.js.map +1 -0
  107. package/dist/observability/logger.d.ts +81 -0
  108. package/dist/observability/logger.d.ts.map +1 -0
  109. package/dist/observability/logger.js +127 -0
  110. package/dist/observability/logger.js.map +1 -0
  111. package/dist/observability/metrics.d.ts +37 -0
  112. package/dist/observability/metrics.d.ts.map +1 -0
  113. package/dist/observability/metrics.js +40 -0
  114. package/dist/observability/metrics.js.map +1 -0
  115. package/dist/observability/redact.d.ts +21 -0
  116. package/dist/observability/redact.d.ts.map +1 -0
  117. package/dist/observability/redact.js +72 -0
  118. package/dist/observability/redact.js.map +1 -0
  119. package/dist/observability/tracer.d.ts +25 -0
  120. package/dist/observability/tracer.d.ts.map +1 -0
  121. package/dist/observability/tracer.js +18 -0
  122. package/dist/observability/tracer.js.map +1 -0
  123. package/dist/payments/client.d.ts +247 -0
  124. package/dist/payments/client.d.ts.map +1 -0
  125. package/dist/payments/client.js +488 -0
  126. package/dist/payments/client.js.map +1 -0
  127. package/dist/payments/index.d.ts +14 -0
  128. package/dist/payments/index.d.ts.map +1 -0
  129. package/dist/payments/index.js +13 -0
  130. package/dist/payments/index.js.map +1 -0
  131. package/dist/refunds/fast-refund-client.d.ts +128 -0
  132. package/dist/refunds/fast-refund-client.d.ts.map +1 -0
  133. package/dist/refunds/fast-refund-client.js +138 -0
  134. package/dist/refunds/fast-refund-client.js.map +1 -0
  135. package/dist/refunds/index.d.ts +19 -0
  136. package/dist/refunds/index.d.ts.map +1 -0
  137. package/dist/refunds/index.js +17 -0
  138. package/dist/refunds/index.js.map +1 -0
  139. package/dist/refunds/strategy.d.ts +78 -0
  140. package/dist/refunds/strategy.d.ts.map +1 -0
  141. package/dist/refunds/strategy.js +75 -0
  142. package/dist/refunds/strategy.js.map +1 -0
  143. package/dist/types/auth.d.ts +80 -0
  144. package/dist/types/auth.d.ts.map +1 -0
  145. package/dist/types/auth.js +12 -0
  146. package/dist/types/auth.js.map +1 -0
  147. package/dist/types/card-types.d.ts +48 -0
  148. package/dist/types/card-types.d.ts.map +1 -0
  149. package/dist/types/card-types.js +62 -0
  150. package/dist/types/card-types.js.map +1 -0
  151. package/dist/types/common.d.ts +160 -0
  152. package/dist/types/common.d.ts.map +1 -0
  153. package/dist/types/common.js +70 -0
  154. package/dist/types/common.js.map +1 -0
  155. package/dist/types/index.d.ts +21 -0
  156. package/dist/types/index.d.ts.map +1 -0
  157. package/dist/types/index.js +21 -0
  158. package/dist/types/index.js.map +1 -0
  159. package/dist/types/isv-accounts.d.ts +109 -0
  160. package/dist/types/isv-accounts.d.ts.map +1 -0
  161. package/dist/types/isv-accounts.js +22 -0
  162. package/dist/types/isv-accounts.js.map +1 -0
  163. package/dist/types/isv-payments.d.ts +262 -0
  164. package/dist/types/isv-payments.d.ts.map +1 -0
  165. package/dist/types/isv-payments.js +19 -0
  166. package/dist/types/isv-payments.js.map +1 -0
  167. package/dist/types/status.d.ts +125 -0
  168. package/dist/types/status.d.ts.map +1 -0
  169. package/dist/types/status.js +19 -0
  170. package/dist/types/status.js.map +1 -0
  171. package/dist/types/webhook-events.d.ts +447 -0
  172. package/dist/types/webhook-events.d.ts.map +1 -0
  173. package/dist/types/webhook-events.js +76 -0
  174. package/dist/types/webhook-events.js.map +1 -0
  175. package/dist/webhooks/challenge-response.d.ts +28 -0
  176. package/dist/webhooks/challenge-response.d.ts.map +1 -0
  177. package/dist/webhooks/challenge-response.js +35 -0
  178. package/dist/webhooks/challenge-response.js.map +1 -0
  179. package/dist/webhooks/event-types.d.ts +44 -0
  180. package/dist/webhooks/event-types.d.ts.map +1 -0
  181. package/dist/webhooks/event-types.js +50 -0
  182. package/dist/webhooks/event-types.js.map +1 -0
  183. package/dist/webhooks/extract-client-ip.d.ts +40 -0
  184. package/dist/webhooks/extract-client-ip.d.ts.map +1 -0
  185. package/dist/webhooks/extract-client-ip.js +72 -0
  186. package/dist/webhooks/extract-client-ip.js.map +1 -0
  187. package/dist/webhooks/hmac-verify.d.ts +38 -0
  188. package/dist/webhooks/hmac-verify.d.ts.map +1 -0
  189. package/dist/webhooks/hmac-verify.js +92 -0
  190. package/dist/webhooks/hmac-verify.js.map +1 -0
  191. package/dist/webhooks/index.d.ts +19 -0
  192. package/dist/webhooks/index.d.ts.map +1 -0
  193. package/dist/webhooks/index.js +19 -0
  194. package/dist/webhooks/index.js.map +1 -0
  195. package/dist/webhooks/ip-allowlist.d.ts +59 -0
  196. package/dist/webhooks/ip-allowlist.d.ts.map +1 -0
  197. package/dist/webhooks/ip-allowlist.js +147 -0
  198. package/dist/webhooks/ip-allowlist.js.map +1 -0
  199. package/dist/webhooks/status-lattice.d.ts +72 -0
  200. package/dist/webhooks/status-lattice.d.ts.map +1 -0
  201. package/dist/webhooks/status-lattice.js +208 -0
  202. package/dist/webhooks/status-lattice.js.map +1 -0
  203. package/package.json +85 -0
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Single-flight primitives for token refresh.
3
+ *
4
+ * `AsyncMutex` serializes concurrent in-process callers on a single key.
5
+ * `singleFlight()` ensures that when N callers race, only one fn() executes
6
+ * and all N receive the same resolved value.
7
+ *
8
+ * For multi-worker deployments a Redis-based lock must be injected via
9
+ * `RedisLockClient`. The interface is declared here; no Redis runtime dep
10
+ * is included in this package — the SaaS layer provides the concrete impl.
11
+ *
12
+ * Plan ref (A1): forceRefresh on 401 recovery MUST go through the same
13
+ * single-flight to prevent token stampede during secret rotation.
14
+ */
15
+ /**
16
+ * A no-op sentinel implementation that throws if actually invoked.
17
+ * Satisfies the type when Redis is not configured; safe to pass as default
18
+ * so callers don't need to guard for undefined.
19
+ */
20
+ export const noopRedisLock = {
21
+ acquire() {
22
+ throw new Error('RedisLockClient not configured. Provide a concrete implementation.');
23
+ },
24
+ release() {
25
+ throw new Error('RedisLockClient not configured. Provide a concrete implementation.');
26
+ },
27
+ pollCacheUntil() {
28
+ throw new Error('RedisLockClient not configured. Provide a concrete implementation.');
29
+ },
30
+ };
31
+ // ---------------------------------------------------------------------------
32
+ // In-process async mutex
33
+ // ---------------------------------------------------------------------------
34
+ /**
35
+ * A simple in-process serialising mutex.
36
+ *
37
+ * `acquire()` returns a release function. Callers MUST call the release
38
+ * function in a `finally` block to avoid deadlocks.
39
+ *
40
+ * Internally, each acquire appends a promise to a chain. When the current
41
+ * holder calls release it resolves the next waiter.
42
+ */
43
+ export class AsyncMutex {
44
+ _tail = Promise.resolve();
45
+ /**
46
+ * Acquires the mutex. Resolves when this caller holds the lock.
47
+ * Returns a `release` function that MUST be called in `finally`.
48
+ */
49
+ acquire() {
50
+ // Capture the current tail before appending so this waiter chains after it.
51
+ const prevTail = this._tail;
52
+ let resolve;
53
+ // Our slot in the queue: resolves when we call release.
54
+ const ourTurn = new Promise((res) => {
55
+ resolve = res;
56
+ });
57
+ // The new tail that subsequent acquirers will wait on.
58
+ this._tail = ourTurn;
59
+ // We expose a promise that resolves with the release function once it
60
+ // is our turn to hold the lock.
61
+ return prevTail.then(() => resolve);
62
+ }
63
+ }
64
+ /**
65
+ * Per-key in-flight promises. When a call is in progress, all concurrent
66
+ * callers with the same key share this promise instead of calling fn() again.
67
+ *
68
+ * The map is keyed by the singleFlight key. Entries are removed when the
69
+ * promise settles (whether resolved or rejected).
70
+ */
71
+ const inFlight = new Map();
72
+ /**
73
+ * Ensures that concurrent calls with the same `key` execute `fn` exactly once.
74
+ * All concurrent waiters share the same promise and receive the same result.
75
+ *
76
+ * Design: the in-flight map is checked and populated BEFORE acquiring the mutex.
77
+ * - If an entry exists: await it directly (no mutex needed, no fn() call).
78
+ * - If no entry: create the shared promise, store it, then acquire the mutex
79
+ * for the re-check + fn() execution. Other concurrent callers that arrive
80
+ * between "check" and "set" will see the entry in the map on their first
81
+ * check and coalesce.
82
+ *
83
+ * When a `{ local: AsyncMutex }` is provided the mutex is used to serialise
84
+ * the actual fn() execution. The map handles the N-1 waiters.
85
+ *
86
+ * When a `{ redis: RedisLockClient }` is provided the first worker to acquire
87
+ * the Redis lock runs fn(). Other workers (including other processes) poll
88
+ * the cache via `pollCacheUntil` until the result is available.
89
+ *
90
+ * @see plan line 311 — Redis lock key pattern: `viva:isv:token:lock:{client_id}`
91
+ */
92
+ export function singleFlight(key, fn, locks) {
93
+ if ('local' in locks) {
94
+ // ---- In-process path ----
95
+ // Fast path: if there is already an in-flight promise, piggy-back on it.
96
+ const existing = inFlight.get(key);
97
+ if (existing !== undefined) {
98
+ return existing;
99
+ }
100
+ // No in-flight entry yet. We create a new shared promise and register it
101
+ // SYNCHRONOUSLY before yielding, so any concurrent caller that arrives
102
+ // on the next tick (or even in the same microtask batch) will find it.
103
+ let resolveFlight;
104
+ let rejectFlight;
105
+ const shared = new Promise((res, rej) => {
106
+ resolveFlight = res;
107
+ rejectFlight = rej;
108
+ });
109
+ // Register before awaiting anything — this is the critical window.
110
+ inFlight.set(key, shared);
111
+ // Now do the actual work: acquire the mutex and run fn().
112
+ // We return the shared promise to our own caller as well.
113
+ void (async () => {
114
+ const release = await locks.local.acquire();
115
+ try {
116
+ // Re-check: another waiter may have refreshed while we waited on mutex.
117
+ // (This re-check is relevant when multiple singleFlight calls for the
118
+ // same key arrive before the first one has set inFlight — but since we
119
+ // now set inFlight synchronously that window is much narrower. Still
120
+ // call the re-check for correctness in the mutex-queue case.)
121
+ const result = await fn();
122
+ resolveFlight(result);
123
+ }
124
+ catch (err) {
125
+ rejectFlight(err);
126
+ }
127
+ finally {
128
+ inFlight.delete(key);
129
+ release();
130
+ }
131
+ })();
132
+ return shared;
133
+ }
134
+ else {
135
+ // ---- Redis path ----
136
+ const lockKey = `${key}:lock`;
137
+ return (async () => {
138
+ const lockResult = await locks.redis.acquire(lockKey, 30_000);
139
+ if (lockResult !== null) {
140
+ // This worker won the lock — run fn() and release.
141
+ try {
142
+ return await fn();
143
+ }
144
+ finally {
145
+ await locks.redis.release(lockKey, lockResult.token);
146
+ }
147
+ }
148
+ else {
149
+ // Another worker holds the lock — poll the cache until it writes the result.
150
+ const cached = await locks.redis.pollCacheUntil(async () => null, // caller provides a real getter at the strategy level
151
+ 100, 10_000);
152
+ if (cached !== null)
153
+ return cached;
154
+ // Fallback: run fn() ourselves if the poll timed out.
155
+ return fn();
156
+ }
157
+ })();
158
+ }
159
+ }
160
+ //# sourceMappingURL=single-flight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-flight.js","sourceRoot":"","sources":["../../src/auth/single-flight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * TokenCache interface and built-in implementations.
3
+ *
4
+ * `InMemoryTokenCache` is the default for single-worker deployments.
5
+ * `RedisTokenCache` is declared as an interface; the SaaS layer provides
6
+ * the concrete implementation via dependency injection (plan P11, Q3).
7
+ */
8
+ import type { CachedToken } from '../types/auth.js';
9
+ export interface TokenCache {
10
+ get(key: string): Promise<CachedToken | null>;
11
+ set(key: string, value: CachedToken): Promise<void>;
12
+ delete(key: string): Promise<void>;
13
+ }
14
+ export declare class InMemoryTokenCache implements TokenCache {
15
+ private readonly _store;
16
+ /** Injectable clock; defaults to `Date.now`. Allows time-travel in tests. */
17
+ private readonly _now;
18
+ constructor(opts?: {
19
+ now?: () => number;
20
+ });
21
+ get(key: string): Promise<CachedToken | null>;
22
+ set(key: string, value: CachedToken): Promise<void>;
23
+ delete(key: string): Promise<void>;
24
+ }
25
+ /**
26
+ * Redis-backed token cache interface.
27
+ *
28
+ * The concrete implementation lives in the SaaS package. It is injected via
29
+ * `OAuth2ClientCredentialsStrategy.cache` option at construction time.
30
+ *
31
+ * Plan Q3: the interface is published from day one so future adapters
32
+ * (Memcached, ElastiCache) are additive, not structural changes.
33
+ */
34
+ export interface RedisTokenCacheClient {
35
+ get(key: string): Promise<string | null>;
36
+ set(key: string, value: string, ttlMs: number): Promise<void>;
37
+ delete(key: string): Promise<void>;
38
+ }
39
+ /**
40
+ * Thin wrapper that adapts a `RedisTokenCacheClient` to the `TokenCache`
41
+ * interface by JSON-serialising `CachedToken` values.
42
+ */
43
+ export declare class RedisTokenCache implements TokenCache {
44
+ private readonly client;
45
+ constructor(client: RedisTokenCacheClient);
46
+ get(key: string): Promise<CachedToken | null>;
47
+ set(key: string, value: CachedToken): Promise<void>;
48
+ delete(key: string): Promise<void>;
49
+ }
50
+ //# sourceMappingURL=token-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-cache.d.ts","sourceRoot":"","sources":["../../src/auth/token-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAMpD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAMD,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IAEzD,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;gBAExB,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE;IAInC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAW7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGzC;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,UAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,qBAAqB;IAEpD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAM7C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGzC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * TokenCache interface and built-in implementations.
3
+ *
4
+ * `InMemoryTokenCache` is the default for single-worker deployments.
5
+ * `RedisTokenCache` is declared as an interface; the SaaS layer provides
6
+ * the concrete implementation via dependency injection (plan P11, Q3).
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // In-memory implementation
10
+ // ---------------------------------------------------------------------------
11
+ export class InMemoryTokenCache {
12
+ _store = new Map();
13
+ /** Injectable clock; defaults to `Date.now`. Allows time-travel in tests. */
14
+ _now;
15
+ constructor(opts) {
16
+ this._now = opts?.now ?? (() => Date.now());
17
+ }
18
+ async get(key) {
19
+ const entry = this._store.get(key);
20
+ if (!entry)
21
+ return null;
22
+ // Treat as expired if the current time is at or past `expires_at`.
23
+ if (this._now() >= entry.expires_at) {
24
+ this._store.delete(key);
25
+ return null;
26
+ }
27
+ return entry;
28
+ }
29
+ async set(key, value) {
30
+ this._store.set(key, value);
31
+ }
32
+ async delete(key) {
33
+ this._store.delete(key);
34
+ }
35
+ }
36
+ /**
37
+ * Thin wrapper that adapts a `RedisTokenCacheClient` to the `TokenCache`
38
+ * interface by JSON-serialising `CachedToken` values.
39
+ */
40
+ export class RedisTokenCache {
41
+ client;
42
+ constructor(client) {
43
+ this.client = client;
44
+ }
45
+ async get(key) {
46
+ const raw = await this.client.get(key);
47
+ if (!raw)
48
+ return null;
49
+ return JSON.parse(raw);
50
+ }
51
+ async set(key, value) {
52
+ const ttlMs = Math.max(0, value.expires_at - Date.now());
53
+ await this.client.set(key, JSON.stringify(value), ttlMs);
54
+ }
55
+ async delete(key) {
56
+ await this.client.delete(key);
57
+ }
58
+ }
59
+ //# sourceMappingURL=token-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-cache.js","sourceRoot":"","sources":["../../src/auth/token-cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E,MAAM,OAAO,kBAAkB;IACZ,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEzD,6EAA6E;IAC5D,IAAI,CAAe;IAEpC,YAAY,IAA6B;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,mEAAmE;QACnE,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAkB;QACvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF;AAqBD;;;GAGG;AACH,MAAM,OAAO,eAAe;IACG;IAA7B,YAA6B,MAA6B;QAA7B,WAAM,GAAN,MAAM,CAAuB;IAAG,CAAC;IAE9D,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAkB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import { VivaError, type VivaErrorOptions } from './base.js';
2
+ /**
3
+ * Thrown when the Viva API returns a 4xx or 5xx response on a non-auth call,
4
+ * or when a network-level error occurs.
5
+ *
6
+ * The `vivaCode` field carries Viva's error code from the response body when
7
+ * available. The `cause` field wraps the underlying network or fetch error.
8
+ *
9
+ * Maps to `MedusaError(Types.PAYMENT_AUTHORIZATION_ERROR)` in the adapter.
10
+ */
11
+ export declare class VivaApiError extends VivaError {
12
+ readonly code: "VIVA_API_ERROR";
13
+ constructor(opts: VivaErrorOptions);
14
+ }
15
+ //# sourceMappingURL=api-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-error.d.ts","sourceRoot":"","sources":["../../src/errors/api-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D;;;;;;;;GAQG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC,QAAQ,CAAC,IAAI,EAAG,gBAAgB,CAAU;gBAE9B,IAAI,EAAE,gBAAgB;CAInC"}
@@ -0,0 +1,18 @@
1
+ import { VivaError } from './base.js';
2
+ /**
3
+ * Thrown when the Viva API returns a 4xx or 5xx response on a non-auth call,
4
+ * or when a network-level error occurs.
5
+ *
6
+ * The `vivaCode` field carries Viva's error code from the response body when
7
+ * available. The `cause` field wraps the underlying network or fetch error.
8
+ *
9
+ * Maps to `MedusaError(Types.PAYMENT_AUTHORIZATION_ERROR)` in the adapter.
10
+ */
11
+ export class VivaApiError extends VivaError {
12
+ code = 'VIVA_API_ERROR';
13
+ constructor(opts) {
14
+ super(opts);
15
+ this.name = 'VivaApiError';
16
+ }
17
+ }
18
+ //# sourceMappingURL=api-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-error.js","sourceRoot":"","sources":["../../src/errors/api-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,OAAO,YAAa,SAAQ,SAAS;IAChC,IAAI,GAAG,gBAAyB,CAAC;IAE1C,YAAY,IAAsB;QAChC,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import { VivaError, type VivaErrorOptions } from './base.js';
2
+ /**
3
+ * Thrown when authentication with Viva fails.
4
+ *
5
+ * Causes: bad credentials, expired token, 401/403 from `/connect/token`,
6
+ * or a second 401 after a forced token refresh (likely rotated client_secret).
7
+ *
8
+ * Maps to `MedusaError(Types.UNAUTHORIZED)` in the Medusa adapter layer.
9
+ */
10
+ export declare class VivaAuthError extends VivaError {
11
+ readonly code: "VIVA_AUTH_ERROR";
12
+ constructor(opts: VivaErrorOptions);
13
+ }
14
+ //# sourceMappingURL=auth-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-error.d.ts","sourceRoot":"","sources":["../../src/errors/auth-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC1C,QAAQ,CAAC,IAAI,EAAG,iBAAiB,CAAU;gBAE/B,IAAI,EAAE,gBAAgB;CAInC"}
@@ -0,0 +1,17 @@
1
+ import { VivaError } from './base.js';
2
+ /**
3
+ * Thrown when authentication with Viva fails.
4
+ *
5
+ * Causes: bad credentials, expired token, 401/403 from `/connect/token`,
6
+ * or a second 401 after a forced token refresh (likely rotated client_secret).
7
+ *
8
+ * Maps to `MedusaError(Types.UNAUTHORIZED)` in the Medusa adapter layer.
9
+ */
10
+ export class VivaAuthError extends VivaError {
11
+ code = 'VIVA_AUTH_ERROR';
12
+ constructor(opts) {
13
+ super(opts);
14
+ this.name = 'VivaAuthError';
15
+ }
16
+ }
17
+ //# sourceMappingURL=auth-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-error.js","sourceRoot":"","sources":["../../src/errors/auth-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,OAAO,aAAc,SAAQ,SAAS;IACjC,IAAI,GAAG,iBAA0B,CAAC;IAE3C,YAAY,IAAsB;QAChC,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Abstract base class for all Viva Wallet errors.
3
+ *
4
+ * Every error carries a plugin-stable `code`, optional Viva API error code,
5
+ * HTTP status, request correlation ID, and an ES2022-style `cause` chain.
6
+ *
7
+ * Subclasses implement `abstract readonly code: string` with a literal value.
8
+ */
9
+ export interface VivaErrorOptions {
10
+ message: string;
11
+ vivaCode?: string | undefined;
12
+ httpStatus?: number | undefined;
13
+ requestId?: string | undefined;
14
+ /**
15
+ * Viva `x-viva-correlationid` response header value.
16
+ * Probe-verified 2026-04-25: present on every Viva API response.
17
+ * Example: "26-115-EDAA55BC". Use for end-to-end tracing + Viva support tickets.
18
+ */
19
+ vivaCorrelationId?: string | undefined;
20
+ /**
21
+ * Viva `x-viva-eventid` response header value.
22
+ * Probe-verified 2026-04-25: present on every Viva API response.
23
+ * Example: "0".
24
+ */
25
+ vivaEventId?: string | undefined;
26
+ cause?: unknown;
27
+ }
28
+ export declare abstract class VivaError extends Error {
29
+ /**
30
+ * Plugin-stable string identifier for the error type.
31
+ * Consumers use this for programmatic branching — never match on `message`.
32
+ */
33
+ abstract readonly code: string;
34
+ /** Viva's own error code extracted from the response body, if available. */
35
+ readonly vivaCode: string | undefined;
36
+ /** HTTP status from the Viva API response, if available. */
37
+ readonly httpStatus: number | undefined;
38
+ /**
39
+ * Viva `CorrelationId` response header, or a locally generated ID.
40
+ * Use this for cross-system correlation when filing support tickets.
41
+ */
42
+ readonly requestId: string | undefined;
43
+ /**
44
+ * Viva `x-viva-correlationid` response header value.
45
+ * Probe-verified 2026-04-25: present on every Viva API response.
46
+ * Example: "26-115-EDAA55BC". Use for end-to-end tracing + Viva support tickets.
47
+ */
48
+ readonly vivaCorrelationId: string | undefined;
49
+ /**
50
+ * Viva `x-viva-eventid` response header value.
51
+ * Probe-verified 2026-04-25: present on every Viva API response.
52
+ * Example: "0".
53
+ */
54
+ readonly vivaEventId: string | undefined;
55
+ /** Chained cause per ES2022 Error.cause semantics. */
56
+ readonly cause: unknown;
57
+ constructor({ message, vivaCode, httpStatus, requestId, vivaCorrelationId, vivaEventId, cause }: VivaErrorOptions);
58
+ }
59
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/errors/base.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,8BAAsB,SAAU,SAAQ,KAAK;IAC3C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzC,sDAAsD;IACtD,SAAkB,KAAK,EAAE,OAAO,CAAC;gBAErB,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,gBAAgB;CAkBlH"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Abstract base class for all Viva Wallet errors.
3
+ *
4
+ * Every error carries a plugin-stable `code`, optional Viva API error code,
5
+ * HTTP status, request correlation ID, and an ES2022-style `cause` chain.
6
+ *
7
+ * Subclasses implement `abstract readonly code: string` with a literal value.
8
+ */
9
+ export class VivaError extends Error {
10
+ /** Viva's own error code extracted from the response body, if available. */
11
+ vivaCode;
12
+ /** HTTP status from the Viva API response, if available. */
13
+ httpStatus;
14
+ /**
15
+ * Viva `CorrelationId` response header, or a locally generated ID.
16
+ * Use this for cross-system correlation when filing support tickets.
17
+ */
18
+ requestId;
19
+ /**
20
+ * Viva `x-viva-correlationid` response header value.
21
+ * Probe-verified 2026-04-25: present on every Viva API response.
22
+ * Example: "26-115-EDAA55BC". Use for end-to-end tracing + Viva support tickets.
23
+ */
24
+ vivaCorrelationId;
25
+ /**
26
+ * Viva `x-viva-eventid` response header value.
27
+ * Probe-verified 2026-04-25: present on every Viva API response.
28
+ * Example: "0".
29
+ */
30
+ vivaEventId;
31
+ /** Chained cause per ES2022 Error.cause semantics. */
32
+ cause;
33
+ constructor({ message, vivaCode, httpStatus, requestId, vivaCorrelationId, vivaEventId, cause }) {
34
+ super(message);
35
+ // Ensure the prototype chain is correct for `instanceof` checks when
36
+ // targeting ES5 or when transpiled.
37
+ Object.setPrototypeOf(this, new.target.prototype);
38
+ this.name = new.target.name;
39
+ this.vivaCode = vivaCode;
40
+ this.httpStatus = httpStatus;
41
+ this.requestId = requestId;
42
+ this.vivaCorrelationId = vivaCorrelationId;
43
+ this.vivaEventId = vivaEventId;
44
+ this.cause = cause;
45
+ // V8 / Node.js: remove the constructor frame from the stack trace.
46
+ if (Error.captureStackTrace) {
47
+ Error.captureStackTrace(this, new.target);
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/errors/base.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuBH,MAAM,OAAgB,SAAU,SAAQ,KAAK;IAO3C,4EAA4E;IACnE,QAAQ,CAAqB;IAEtC,4DAA4D;IACnD,UAAU,CAAqB;IAExC;;;OAGG;IACM,SAAS,CAAqB;IAEvC;;;;OAIG;IACM,iBAAiB,CAAqB;IAE/C;;;;OAIG;IACM,WAAW,CAAqB;IAEzC,sDAAsD;IACpC,KAAK,CAAU;IAEjC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,EAAoB;QAC/G,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,qEAAqE;QACrE,oCAAoC;QACpC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,mEAAmE;QACnE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * viva-payments-core/errors — barrel export.
3
+ *
4
+ * Subpath: `viva-payments-core/errors`
5
+ *
6
+ * All error classes extend `VivaError`. Callers can do:
7
+ * import { VivaError, VivaAuthError, VivaRateLimitError } from 'viva-payments-core/errors';
8
+ */
9
+ export { VivaError } from './base.js';
10
+ export type { VivaErrorOptions } from './base.js';
11
+ export { VivaAuthError } from './auth-error.js';
12
+ export { VivaApiError } from './api-error.js';
13
+ export { VivaValidationError } from './validation-error.js';
14
+ export { VivaWebhookError } from './webhook-error.js';
15
+ export { VivaRateLimitError } from './rate-limit-error.js';
16
+ export type { VivaRateLimitErrorOptions } from './rate-limit-error.js';
17
+ export { VivaModeMismatchError } from './mode-mismatch-error.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * viva-payments-core/errors — barrel export.
3
+ *
4
+ * Subpath: `viva-payments-core/errors`
5
+ *
6
+ * All error classes extend `VivaError`. Callers can do:
7
+ * import { VivaError, VivaAuthError, VivaRateLimitError } from 'viva-payments-core/errors';
8
+ */
9
+ export { VivaError } from './base.js';
10
+ export { VivaAuthError } from './auth-error.js';
11
+ export { VivaApiError } from './api-error.js';
12
+ export { VivaValidationError } from './validation-error.js';
13
+ export { VivaWebhookError } from './webhook-error.js';
14
+ export { VivaRateLimitError } from './rate-limit-error.js';
15
+ export { VivaModeMismatchError } from './mode-mismatch-error.js';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { VivaError, type VivaErrorOptions } from './base.js';
2
+ /**
3
+ * Thrown when a code path is invoked under the wrong plugin mode.
4
+ *
5
+ * Example: an ISV-only endpoint (e.g. POST /api/sources, the Connected
6
+ * Accounts webhook subscriber, the ISV tenant resolver) is invoked while
7
+ * `VivaPluginConfig.mode === 'merchant'`. Or, in a future merchant-only
8
+ * code path, while `mode === 'isv'`.
9
+ *
10
+ * Plan multi-mode-v0 §5 (config shape) + §10.1 (Vendure parallel).
11
+ * Migration 0.1→0.2 §2.2.
12
+ *
13
+ * Maps to `MedusaError(Types.NOT_ALLOWED)` in the adapter layer.
14
+ */
15
+ export declare class VivaModeMismatchError extends VivaError {
16
+ readonly code: "VIVA_MODE_MISMATCH";
17
+ constructor(opts: VivaErrorOptions);
18
+ }
19
+ //# sourceMappingURL=mode-mismatch-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-mismatch-error.d.ts","sourceRoot":"","sources":["../../src/errors/mode-mismatch-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;IAClD,QAAQ,CAAC,IAAI,EAAG,oBAAoB,CAAU;gBAElC,IAAI,EAAE,gBAAgB;CAInC"}
@@ -0,0 +1,22 @@
1
+ import { VivaError } from './base.js';
2
+ /**
3
+ * Thrown when a code path is invoked under the wrong plugin mode.
4
+ *
5
+ * Example: an ISV-only endpoint (e.g. POST /api/sources, the Connected
6
+ * Accounts webhook subscriber, the ISV tenant resolver) is invoked while
7
+ * `VivaPluginConfig.mode === 'merchant'`. Or, in a future merchant-only
8
+ * code path, while `mode === 'isv'`.
9
+ *
10
+ * Plan multi-mode-v0 §5 (config shape) + §10.1 (Vendure parallel).
11
+ * Migration 0.1→0.2 §2.2.
12
+ *
13
+ * Maps to `MedusaError(Types.NOT_ALLOWED)` in the adapter layer.
14
+ */
15
+ export class VivaModeMismatchError extends VivaError {
16
+ code = 'VIVA_MODE_MISMATCH';
17
+ constructor(opts) {
18
+ super(opts);
19
+ this.name = 'VivaModeMismatchError';
20
+ }
21
+ }
22
+ //# sourceMappingURL=mode-mismatch-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-mismatch-error.js","sourceRoot":"","sources":["../../src/errors/mode-mismatch-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAE7D;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAsB,SAAQ,SAAS;IACzC,IAAI,GAAG,oBAA6B,CAAC;IAE9C,YAAY,IAAsB;QAChC,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import { VivaError, type VivaErrorOptions } from './base.js';
2
+ export interface VivaRateLimitErrorOptions extends VivaErrorOptions {
3
+ /** Milliseconds to wait before retrying, derived from `Retry-After` header. */
4
+ retryAfterMs?: number | undefined;
5
+ }
6
+ /**
7
+ * Thrown when Viva returns HTTP 429 (Too Many Requests) or a retriable 5xx.
8
+ *
9
+ * `retriable` is always `true`. The caller (or retry policy in S3) uses
10
+ * `retryAfterMs` when present; otherwise falls back to exponential backoff
11
+ * per plan Auth Flow line 319.
12
+ */
13
+ export declare class VivaRateLimitError extends VivaError {
14
+ readonly code: "VIVA_RATE_LIMIT_ERROR";
15
+ readonly retriable: true;
16
+ /** Milliseconds to wait before retrying, from `Retry-After` header. */
17
+ readonly retryAfterMs: number | undefined;
18
+ constructor(opts: VivaRateLimitErrorOptions);
19
+ }
20
+ //# sourceMappingURL=rate-limit-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-error.d.ts","sourceRoot":"","sources":["../../src/errors/rate-limit-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB;IACjE,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,IAAI,EAAG,uBAAuB,CAAU;IACjD,QAAQ,CAAC,SAAS,EAAG,IAAI,CAAU;IAEnC,uEAAuE;IACvE,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE9B,IAAI,EAAE,yBAAyB;CAK5C"}
@@ -0,0 +1,20 @@
1
+ import { VivaError } from './base.js';
2
+ /**
3
+ * Thrown when Viva returns HTTP 429 (Too Many Requests) or a retriable 5xx.
4
+ *
5
+ * `retriable` is always `true`. The caller (or retry policy in S3) uses
6
+ * `retryAfterMs` when present; otherwise falls back to exponential backoff
7
+ * per plan Auth Flow line 319.
8
+ */
9
+ export class VivaRateLimitError extends VivaError {
10
+ code = 'VIVA_RATE_LIMIT_ERROR';
11
+ retriable = true;
12
+ /** Milliseconds to wait before retrying, from `Retry-After` header. */
13
+ retryAfterMs;
14
+ constructor(opts) {
15
+ super(opts);
16
+ this.name = 'VivaRateLimitError';
17
+ this.retryAfterMs = opts.retryAfterMs;
18
+ }
19
+ }
20
+ //# sourceMappingURL=rate-limit-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-error.js","sourceRoot":"","sources":["../../src/errors/rate-limit-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAO7D;;;;;;GAMG;AACH,MAAM,OAAO,kBAAmB,SAAQ,SAAS;IACtC,IAAI,GAAG,uBAAgC,CAAC;IACxC,SAAS,GAAG,IAAa,CAAC;IAEnC,uEAAuE;IAC9D,YAAY,CAAqB;IAE1C,YAAY,IAA+B;QACzC,KAAK,CAAC,IAAI,CAAC,CAAC;QACZ,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACxC,CAAC;CACF"}