@burdenoff/be-sdk 2026.510.79

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 (220) hide show
  1. package/README.md +173 -0
  2. package/configs/eslint/index.js +492 -0
  3. package/configs/tsconfig/tsconfig.json +53 -0
  4. package/dist/EventQueueFactory-6NMSGECR.js +8 -0
  5. package/dist/EventQueueFactory-6NMSGECR.js.map +1 -0
  6. package/dist/auth/index.d.ts +66 -0
  7. package/dist/auth/index.js +8 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/cache/index.d.ts +2 -0
  10. package/dist/cache/index.js +6 -0
  11. package/dist/cache/index.js.map +1 -0
  12. package/dist/captcha/index.d.ts +1 -0
  13. package/dist/captcha/index.js +4 -0
  14. package/dist/captcha/index.js.map +1 -0
  15. package/dist/chunk-2HANKZZM.js +245 -0
  16. package/dist/chunk-2HANKZZM.js.map +1 -0
  17. package/dist/chunk-2SD5L2F2.js +816 -0
  18. package/dist/chunk-2SD5L2F2.js.map +1 -0
  19. package/dist/chunk-3O2RQOPV.js +1068 -0
  20. package/dist/chunk-3O2RQOPV.js.map +1 -0
  21. package/dist/chunk-4B43DZIS.js +560 -0
  22. package/dist/chunk-4B43DZIS.js.map +1 -0
  23. package/dist/chunk-4XAEES25.js +2444 -0
  24. package/dist/chunk-4XAEES25.js.map +1 -0
  25. package/dist/chunk-4XGGWW36.js +1405 -0
  26. package/dist/chunk-4XGGWW36.js.map +1 -0
  27. package/dist/chunk-5LXDPGDH.js +245 -0
  28. package/dist/chunk-5LXDPGDH.js.map +1 -0
  29. package/dist/chunk-AI7L22ZJ.js +472 -0
  30. package/dist/chunk-AI7L22ZJ.js.map +1 -0
  31. package/dist/chunk-CBZNP6RF.js +286 -0
  32. package/dist/chunk-CBZNP6RF.js.map +1 -0
  33. package/dist/chunk-ELLX3K54.js +613 -0
  34. package/dist/chunk-ELLX3K54.js.map +1 -0
  35. package/dist/chunk-F5XEAGHQ.js +1875 -0
  36. package/dist/chunk-F5XEAGHQ.js.map +1 -0
  37. package/dist/chunk-FNZEQOJY.js +628 -0
  38. package/dist/chunk-FNZEQOJY.js.map +1 -0
  39. package/dist/chunk-GTEMQXCA.js +516 -0
  40. package/dist/chunk-GTEMQXCA.js.map +1 -0
  41. package/dist/chunk-HIWTWIGQ.js +226 -0
  42. package/dist/chunk-HIWTWIGQ.js.map +1 -0
  43. package/dist/chunk-IYE2NTRX.js +764 -0
  44. package/dist/chunk-IYE2NTRX.js.map +1 -0
  45. package/dist/chunk-J26YGR2U.js +1484 -0
  46. package/dist/chunk-J26YGR2U.js.map +1 -0
  47. package/dist/chunk-JG2FTZPI.js +509 -0
  48. package/dist/chunk-JG2FTZPI.js.map +1 -0
  49. package/dist/chunk-JVBTNSPG.js +1551 -0
  50. package/dist/chunk-JVBTNSPG.js.map +1 -0
  51. package/dist/chunk-L7ZMN2FJ.js +12 -0
  52. package/dist/chunk-L7ZMN2FJ.js.map +1 -0
  53. package/dist/chunk-M5IMU3US.js +473 -0
  54. package/dist/chunk-M5IMU3US.js.map +1 -0
  55. package/dist/chunk-MLW2HPS5.js +1267 -0
  56. package/dist/chunk-MLW2HPS5.js.map +1 -0
  57. package/dist/chunk-MNCGUYLJ.js +269 -0
  58. package/dist/chunk-MNCGUYLJ.js.map +1 -0
  59. package/dist/chunk-MOCUBSTW.js +373 -0
  60. package/dist/chunk-MOCUBSTW.js.map +1 -0
  61. package/dist/chunk-NGMEI42S.js +103 -0
  62. package/dist/chunk-NGMEI42S.js.map +1 -0
  63. package/dist/chunk-NUB5GQTU.js +270 -0
  64. package/dist/chunk-NUB5GQTU.js.map +1 -0
  65. package/dist/chunk-OVSYMNCI.js +145 -0
  66. package/dist/chunk-OVSYMNCI.js.map +1 -0
  67. package/dist/chunk-QLVKMWFA.js +94 -0
  68. package/dist/chunk-QLVKMWFA.js.map +1 -0
  69. package/dist/chunk-SAG6ZYWQ.js +89 -0
  70. package/dist/chunk-SAG6ZYWQ.js.map +1 -0
  71. package/dist/chunk-SAK2JCA7.js +198 -0
  72. package/dist/chunk-SAK2JCA7.js.map +1 -0
  73. package/dist/chunk-SBS4S2PJ.js +100 -0
  74. package/dist/chunk-SBS4S2PJ.js.map +1 -0
  75. package/dist/chunk-SNEOLWXT.js +148 -0
  76. package/dist/chunk-SNEOLWXT.js.map +1 -0
  77. package/dist/chunk-TKBD2ONF.js +564 -0
  78. package/dist/chunk-TKBD2ONF.js.map +1 -0
  79. package/dist/chunk-UBXFIIAW.js +127 -0
  80. package/dist/chunk-UBXFIIAW.js.map +1 -0
  81. package/dist/chunk-VI4VSNTI.js +57 -0
  82. package/dist/chunk-VI4VSNTI.js.map +1 -0
  83. package/dist/chunk-VWCN5PMD.js +268 -0
  84. package/dist/chunk-VWCN5PMD.js.map +1 -0
  85. package/dist/chunk-XC2YD6CF.js +913 -0
  86. package/dist/chunk-XC2YD6CF.js.map +1 -0
  87. package/dist/chunk-XE4OXN2W.js +10 -0
  88. package/dist/chunk-XE4OXN2W.js.map +1 -0
  89. package/dist/chunk-YMZEUTD2.js +110 -0
  90. package/dist/chunk-YMZEUTD2.js.map +1 -0
  91. package/dist/chunk-Z4IRLBWO.js +758 -0
  92. package/dist/chunk-Z4IRLBWO.js.map +1 -0
  93. package/dist/client/internal-client.d.ts +7 -0
  94. package/dist/client/internal-client.js +5 -0
  95. package/dist/client/internal-client.js.map +1 -0
  96. package/dist/client-CSjIrYKS.d.ts +77 -0
  97. package/dist/config-UKE2E3BW.js +4 -0
  98. package/dist/config-UKE2E3BW.js.map +1 -0
  99. package/dist/crypto/index.d.ts +1 -0
  100. package/dist/crypto/index.js +4 -0
  101. package/dist/crypto/index.js.map +1 -0
  102. package/dist/database/index.d.ts +117 -0
  103. package/dist/database/index.js +7 -0
  104. package/dist/database/index.js.map +1 -0
  105. package/dist/dataloader/index.d.ts +1 -0
  106. package/dist/dataloader/index.js +4 -0
  107. package/dist/dataloader/index.js.map +1 -0
  108. package/dist/esm-K6H7EIWK.js +1450 -0
  109. package/dist/esm-K6H7EIWK.js.map +1 -0
  110. package/dist/event-queue/index.d.ts +6 -0
  111. package/dist/event-queue/index.js +10 -0
  112. package/dist/event-queue/index.js.map +1 -0
  113. package/dist/export/index.d.ts +2 -0
  114. package/dist/export/index.js +9 -0
  115. package/dist/export/index.js.map +1 -0
  116. package/dist/feature-flags/index.d.ts +1 -0
  117. package/dist/feature-flags/index.js +4 -0
  118. package/dist/feature-flags/index.js.map +1 -0
  119. package/dist/gateway/index.d.ts +4 -0
  120. package/dist/gateway/index.js +8 -0
  121. package/dist/gateway/index.js.map +1 -0
  122. package/dist/gateway/security/index.d.ts +2 -0
  123. package/dist/gateway/security/index.js +5 -0
  124. package/dist/gateway/security/index.js.map +1 -0
  125. package/dist/graph/index.d.ts +9 -0
  126. package/dist/graph/index.js +13 -0
  127. package/dist/graph/index.js.map +1 -0
  128. package/dist/graph-emitter-Bk0FqD53.d.ts +47 -0
  129. package/dist/graphql/index.d.ts +2 -0
  130. package/dist/graphql/index.js +7 -0
  131. package/dist/graphql/index.js.map +1 -0
  132. package/dist/graphql/services/index.d.ts +24 -0
  133. package/dist/graphql/services/index.js +5 -0
  134. package/dist/graphql/services/index.js.map +1 -0
  135. package/dist/graphql-BAVrUgBF.d.ts +22 -0
  136. package/dist/i18n/index.d.ts +2 -0
  137. package/dist/i18n/index.js +5 -0
  138. package/dist/i18n/index.js.map +1 -0
  139. package/dist/i18n-DA6IPnYy.d.ts +101 -0
  140. package/dist/index-4gKQKZ2B.d.ts +71 -0
  141. package/dist/index-B18rrFru.d.ts +42 -0
  142. package/dist/index-B70b5mYS.d.ts +33 -0
  143. package/dist/index-BMq3lFjj.d.ts +247 -0
  144. package/dist/index-BODgvRtL.d.ts +316 -0
  145. package/dist/index-BS2idbnr.d.ts +874 -0
  146. package/dist/index-BV3G48cH.d.ts +124 -0
  147. package/dist/index-CHbVw5M7.d.ts +73 -0
  148. package/dist/index-Cq_xNjcv.d.ts +602 -0
  149. package/dist/index-CrQgidpx.d.ts +77 -0
  150. package/dist/index-CyVEg86m.d.ts +309 -0
  151. package/dist/index-DOcBnmMe.d.ts +166 -0
  152. package/dist/index-DSOpj8DI.d.ts +17 -0
  153. package/dist/index-DW9q22GH.d.ts +75 -0
  154. package/dist/index-DlFDFyWD.d.ts +55 -0
  155. package/dist/index-DoK0bjhH.d.ts +607 -0
  156. package/dist/index-Dtf6FBaD.d.ts +199 -0
  157. package/dist/index-KVWGHMbS.d.ts +415 -0
  158. package/dist/index-PaojfSdd.d.ts +71 -0
  159. package/dist/index-RU_M5c74.d.ts +163 -0
  160. package/dist/index-UhkH2eaB.d.ts +192 -0
  161. package/dist/index-e_18DzAg.d.ts +18 -0
  162. package/dist/index-jOuh_TKn.d.ts +59 -0
  163. package/dist/index.d.ts +584 -0
  164. package/dist/index.js +2626 -0
  165. package/dist/index.js.map +1 -0
  166. package/dist/init/index.d.ts +2 -0
  167. package/dist/init/index.js +12 -0
  168. package/dist/init/index.js.map +1 -0
  169. package/dist/instrumentation/index.d.ts +3 -0
  170. package/dist/instrumentation/index.js +5 -0
  171. package/dist/instrumentation/index.js.map +1 -0
  172. package/dist/layer/index.d.ts +2 -0
  173. package/dist/layer/index.js +6 -0
  174. package/dist/layer/index.js.map +1 -0
  175. package/dist/layer-DDip18KY.d.ts +67 -0
  176. package/dist/logger/index.d.ts +2 -0
  177. package/dist/logger/index.js +4 -0
  178. package/dist/logger/index.js.map +1 -0
  179. package/dist/middleware/index.d.ts +3 -0
  180. package/dist/middleware/index.js +5 -0
  181. package/dist/middleware/index.js.map +1 -0
  182. package/dist/notifications/index.d.ts +4 -0
  183. package/dist/notifications/index.js +7 -0
  184. package/dist/notifications/index.js.map +1 -0
  185. package/dist/observability/index.d.ts +3 -0
  186. package/dist/observability/index.js +5 -0
  187. package/dist/observability/index.js.map +1 -0
  188. package/dist/pino-logger-RYLGXPHZ.js +5 -0
  189. package/dist/pino-logger-RYLGXPHZ.js.map +1 -0
  190. package/dist/prisma/generator/index.d.ts +1 -0
  191. package/dist/prisma/generator/index.js +228 -0
  192. package/dist/prisma/generator/index.js.map +1 -0
  193. package/dist/prisma/index.d.ts +5 -0
  194. package/dist/prisma/index.js +12 -0
  195. package/dist/prisma/index.js.map +1 -0
  196. package/dist/prisma-extension-krXnYnrN.d.ts +30 -0
  197. package/dist/rbac/index.d.ts +116 -0
  198. package/dist/rbac/index.js +7 -0
  199. package/dist/rbac/index.js.map +1 -0
  200. package/dist/sdk-THO3IWEE.js +136 -0
  201. package/dist/sdk-THO3IWEE.js.map +1 -0
  202. package/dist/server/index.d.ts +359 -0
  203. package/dist/server/index.js +884 -0
  204. package/dist/server/index.js.map +1 -0
  205. package/dist/telemetry/index.d.ts +83 -0
  206. package/dist/telemetry/index.js +209 -0
  207. package/dist/telemetry/index.js.map +1 -0
  208. package/dist/temporal/index.d.ts +148 -0
  209. package/dist/temporal/index.js +6 -0
  210. package/dist/temporal/index.js.map +1 -0
  211. package/dist/tracker/index.d.ts +5 -0
  212. package/dist/tracker/index.js +9 -0
  213. package/dist/tracker/index.js.map +1 -0
  214. package/dist/types-Bo2wkjSP.d.ts +35 -0
  215. package/dist/utils/index.d.ts +1 -0
  216. package/dist/utils/index.js +4 -0
  217. package/dist/utils/index.js.map +1 -0
  218. package/dist/workspace-guard-LHBNK4TG.js +5 -0
  219. package/dist/workspace-guard-LHBNK4TG.js.map +1 -0
  220. package/package.json +241 -0
@@ -0,0 +1,560 @@
1
+ import { security_exports } from './chunk-MLW2HPS5.js';
2
+ import { LayerManager } from './chunk-HIWTWIGQ.js';
3
+ import { DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_GATEWAY_RETRY_CONFIG } from './chunk-NGMEI42S.js';
4
+ import { logger } from './chunk-CBZNP6RF.js';
5
+ import { __export, __name } from './chunk-XE4OXN2W.js';
6
+
7
+ // src/gateway/index.ts
8
+ var gateway_exports = {};
9
+ __export(gateway_exports, {
10
+ CircuitState: () => CircuitState,
11
+ GatewayClient: () => GatewayClient,
12
+ GatewayError: () => GatewayError,
13
+ GatewayErrorType: () => GatewayErrorType,
14
+ Security: () => security_exports,
15
+ createGatewayClient: () => createGatewayClient,
16
+ createGatewayClientFromEnv: () => createGatewayClientFromEnv
17
+ });
18
+
19
+ // src/gateway/service-jwt.ts
20
+ var SIGNING_ENV_VAR = "SERVICE_JWT_SECRET";
21
+ var KEY_ID = "service-v1";
22
+ var DEFAULT_TTL_SECONDS = 60;
23
+ var REFRESH_BEFORE_EXP_MS = 1e4;
24
+ var joseModule = null;
25
+ async function getJose() {
26
+ if (!joseModule) {
27
+ joseModule = await import('jose');
28
+ }
29
+ return joseModule;
30
+ }
31
+ __name(getJose, "getJose");
32
+ var cache = /* @__PURE__ */ new Map();
33
+ function cacheKey(actorId, ttlSeconds) {
34
+ return `${actorId}:${ttlSeconds}`;
35
+ }
36
+ __name(cacheKey, "cacheKey");
37
+ async function signServiceJwt(actorId, ttlSeconds = DEFAULT_TTL_SECONDS) {
38
+ const secret = process.env[SIGNING_ENV_VAR];
39
+ if (!secret) {
40
+ return null;
41
+ }
42
+ const key = cacheKey(actorId, ttlSeconds);
43
+ const cached = cache.get(key);
44
+ if (cached && cached.expiresAtMs - REFRESH_BEFORE_EXP_MS > Date.now()) {
45
+ return cached.token;
46
+ }
47
+ const joseLib = await getJose();
48
+ const encoder = new TextEncoder();
49
+ const keyBytes = encoder.encode(secret);
50
+ const nowSec = Math.floor(Date.now() / 1e3);
51
+ const expSec = nowSec + ttlSeconds;
52
+ const token = await new joseLib.SignJWT({
53
+ actor_type: "service"
54
+ }).setProtectedHeader({
55
+ alg: "HS256",
56
+ typ: "JWT",
57
+ kid: KEY_ID
58
+ }).setSubject(actorId).setIssuer(actorId).setIssuedAt(nowSec).setExpirationTime(expSec).sign(keyBytes);
59
+ cache.set(key, {
60
+ token,
61
+ expiresAtMs: expSec * 1e3
62
+ });
63
+ return token;
64
+ }
65
+ __name(signServiceJwt, "signServiceJwt");
66
+
67
+ // src/gateway/types.ts
68
+ var CircuitState = /* @__PURE__ */ (function(CircuitState2) {
69
+ CircuitState2["CLOSED"] = "CLOSED";
70
+ CircuitState2["OPEN"] = "OPEN";
71
+ CircuitState2["HALF_OPEN"] = "HALF_OPEN";
72
+ return CircuitState2;
73
+ })({});
74
+ var GatewayErrorType = /* @__PURE__ */ (function(GatewayErrorType2) {
75
+ GatewayErrorType2["NETWORK_ERROR"] = "NETWORK_ERROR";
76
+ GatewayErrorType2["TIMEOUT_ERROR"] = "TIMEOUT_ERROR";
77
+ GatewayErrorType2["CIRCUIT_OPEN"] = "CIRCUIT_OPEN";
78
+ GatewayErrorType2["GRAPHQL_ERROR"] = "GRAPHQL_ERROR";
79
+ GatewayErrorType2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
80
+ return GatewayErrorType2;
81
+ })({});
82
+ var GatewayError = class _GatewayError extends Error {
83
+ static {
84
+ __name(this, "GatewayError");
85
+ }
86
+ type;
87
+ gatewayUrl;
88
+ statusCode;
89
+ graphqlErrors;
90
+ cause;
91
+ constructor(message, type, gatewayUrl, options) {
92
+ super(message);
93
+ this.name = "GatewayError";
94
+ this.type = type;
95
+ this.gatewayUrl = gatewayUrl;
96
+ this.statusCode = options?.statusCode;
97
+ this.graphqlErrors = options?.graphqlErrors;
98
+ this.cause = options?.cause;
99
+ Object.setPrototypeOf(this, _GatewayError.prototype);
100
+ }
101
+ };
102
+
103
+ // src/gateway/client.ts
104
+ var uuidv4 = /* @__PURE__ */ __name(() => crypto.randomUUID(), "uuidv4");
105
+ function hasAuthorizationHeader(headers) {
106
+ for (const key of Object.keys(headers)) {
107
+ if (key.toLowerCase() === "authorization") return true;
108
+ }
109
+ return false;
110
+ }
111
+ __name(hasAuthorizationHeader, "hasAuthorizationHeader");
112
+ function resolveBypassPermissionValue(token = process.env["INTERNAL_SERVICE_TOKEN"]) {
113
+ const normalizedToken = token?.trim();
114
+ if (!normalizedToken) {
115
+ throw new Error("INTERNAL_SERVICE_TOKEN must be configured for bypass-enabled gateway calls");
116
+ }
117
+ return normalizedToken;
118
+ }
119
+ __name(resolveBypassPermissionValue, "resolveBypassPermissionValue");
120
+ var CircuitBreaker = class CircuitBreaker2 {
121
+ static {
122
+ __name(this, "CircuitBreaker");
123
+ }
124
+ state = CircuitState.CLOSED;
125
+ failures = 0;
126
+ successes = 0;
127
+ consecutiveFailures = 0;
128
+ lastFailureTime = null;
129
+ lastSuccessTime = null;
130
+ openedAt = null;
131
+ failureTimestamps = [];
132
+ config;
133
+ constructor(config) {
134
+ this.config = config;
135
+ }
136
+ getState() {
137
+ this.checkStateTransition();
138
+ return this.state;
139
+ }
140
+ recordSuccess() {
141
+ this.successes++;
142
+ this.consecutiveFailures = 0;
143
+ this.lastSuccessTime = Date.now();
144
+ if (this.state === CircuitState.HALF_OPEN) {
145
+ this.state = CircuitState.CLOSED;
146
+ this.failures = 0;
147
+ this.failureTimestamps = [];
148
+ this.openedAt = null;
149
+ logger.info("[CircuitBreaker] Circuit closed after successful test");
150
+ }
151
+ }
152
+ recordFailure() {
153
+ this.failures++;
154
+ this.consecutiveFailures++;
155
+ this.lastFailureTime = Date.now();
156
+ this.failureTimestamps.push(Date.now());
157
+ const windowStart = Date.now() - this.config.failureWindow;
158
+ this.failureTimestamps = this.failureTimestamps.filter((t) => t > windowStart);
159
+ if (this.state === CircuitState.CLOSED && this.failureTimestamps.length >= this.config.failureThreshold) {
160
+ this.state = CircuitState.OPEN;
161
+ this.openedAt = Date.now();
162
+ logger.warn("[CircuitBreaker] Circuit opened due to failures", {
163
+ failures: this.failureTimestamps.length,
164
+ threshold: this.config.failureThreshold
165
+ });
166
+ }
167
+ if (this.state === CircuitState.HALF_OPEN) {
168
+ this.state = CircuitState.OPEN;
169
+ this.openedAt = Date.now();
170
+ logger.warn("[CircuitBreaker] Circuit re-opened after failed test");
171
+ }
172
+ }
173
+ allowRequest() {
174
+ this.checkStateTransition();
175
+ switch (this.state) {
176
+ case CircuitState.CLOSED:
177
+ return true;
178
+ case CircuitState.OPEN:
179
+ return false;
180
+ case CircuitState.HALF_OPEN:
181
+ return true;
182
+ default:
183
+ return true;
184
+ }
185
+ }
186
+ forceOpen() {
187
+ this.state = CircuitState.OPEN;
188
+ this.openedAt = Date.now();
189
+ logger.info("[CircuitBreaker] Circuit force-opened");
190
+ }
191
+ forceClose() {
192
+ this.state = CircuitState.CLOSED;
193
+ this.failures = 0;
194
+ this.consecutiveFailures = 0;
195
+ this.failureTimestamps = [];
196
+ this.openedAt = null;
197
+ logger.info("[CircuitBreaker] Circuit force-closed");
198
+ }
199
+ getStats() {
200
+ return {
201
+ state: this.state,
202
+ failures: this.failures,
203
+ successes: this.successes,
204
+ consecutiveFailures: this.consecutiveFailures,
205
+ lastFailureTime: this.lastFailureTime,
206
+ lastSuccessTime: this.lastSuccessTime,
207
+ openedAt: this.openedAt
208
+ };
209
+ }
210
+ checkStateTransition() {
211
+ if (this.state === CircuitState.OPEN && this.openedAt) {
212
+ const elapsed = Date.now() - this.openedAt;
213
+ if (elapsed >= this.config.resetTimeout) {
214
+ this.state = CircuitState.HALF_OPEN;
215
+ logger.info("[CircuitBreaker] Circuit transitioning to half-open");
216
+ }
217
+ }
218
+ }
219
+ };
220
+ var GatewayClient = class {
221
+ static {
222
+ __name(this, "GatewayClient");
223
+ }
224
+ config;
225
+ layerManager;
226
+ internalCircuitBreaker;
227
+ crossLayerCircuitBreaker;
228
+ retryConfig;
229
+ defaultHeaders;
230
+ constructor(config) {
231
+ this.config = {
232
+ timeout: 3e4,
233
+ enableLogging: true,
234
+ ...config
235
+ };
236
+ this.layerManager = new LayerManager({
237
+ layer: config.layer,
238
+ serviceName: config.serviceName,
239
+ serviceIdentity: config.serviceIdentity
240
+ });
241
+ if (config.internalGatewayUrl) ;
242
+ if (config.crossLayerGatewayUrl) ;
243
+ const cbConfig = {
244
+ ...DEFAULT_CIRCUIT_BREAKER_CONFIG,
245
+ ...config.circuitBreaker
246
+ };
247
+ this.internalCircuitBreaker = new CircuitBreaker(cbConfig);
248
+ this.crossLayerCircuitBreaker = new CircuitBreaker(cbConfig);
249
+ this.retryConfig = {
250
+ ...DEFAULT_GATEWAY_RETRY_CONFIG,
251
+ ...config.retry
252
+ };
253
+ this.defaultHeaders = {
254
+ "x-service-identity": this.layerManager.getServiceIdentity(),
255
+ "x-actor-type": "service",
256
+ ...config.defaultHeaders
257
+ };
258
+ logger.debug("[GatewayClient] Initialized", {
259
+ layer: config.layer,
260
+ serviceName: config.serviceName,
261
+ internalUrl: this.getInternalUrl(),
262
+ crossLayerUrl: this.getCrossLayerUrl()
263
+ });
264
+ }
265
+ getInternalUrl() {
266
+ return this.config.internalGatewayUrl || this.layerManager.getInternalGatewayUrl();
267
+ }
268
+ getCrossLayerUrl() {
269
+ return this.config.crossLayerGatewayUrl || this.layerManager.getCrossLayerGatewayUrl();
270
+ }
271
+ /**
272
+ * Execute internal (same layer) GraphQL query/mutation
273
+ */
274
+ async internalQuery(options) {
275
+ const context = this.createRequestContext("internal", options);
276
+ return this.executeWithRetry(this.getInternalUrl(), options, this.internalCircuitBreaker, context, {
277
+ bypassPermission: true
278
+ });
279
+ }
280
+ /**
281
+ * Execute cross-layer GraphQL query/mutation
282
+ */
283
+ async crossLayerQuery(options) {
284
+ const context = this.createRequestContext("cross-layer", options);
285
+ return this.executeWithRetry(
286
+ this.getCrossLayerUrl(),
287
+ options,
288
+ this.crossLayerCircuitBreaker,
289
+ context,
290
+ {
291
+ bypassPermission: false
292
+ }
293
+ // Cross-layer calls go through public gateway
294
+ );
295
+ }
296
+ /**
297
+ * Execute GraphQL query/mutation with explicit gateway URL
298
+ */
299
+ async query(gatewayUrl, options) {
300
+ const context = this.createRequestContext("direct", options);
301
+ return this.executeWithRetry(gatewayUrl, options, this.internalCircuitBreaker, context, {
302
+ bypassPermission: false
303
+ });
304
+ }
305
+ getInternalCircuitBreaker() {
306
+ return this.internalCircuitBreaker;
307
+ }
308
+ getCrossLayerCircuitBreaker() {
309
+ return this.crossLayerCircuitBreaker;
310
+ }
311
+ getHealthStatus() {
312
+ return {
313
+ internal: {
314
+ url: this.getInternalUrl(),
315
+ circuitState: this.internalCircuitBreaker.getState(),
316
+ stats: this.internalCircuitBreaker.getStats()
317
+ },
318
+ crossLayer: {
319
+ url: this.getCrossLayerUrl(),
320
+ circuitState: this.crossLayerCircuitBreaker.getState(),
321
+ stats: this.crossLayerCircuitBreaker.getStats()
322
+ }
323
+ };
324
+ }
325
+ updateDefaultHeaders(headers) {
326
+ this.defaultHeaders = {
327
+ ...this.defaultHeaders,
328
+ ...headers
329
+ };
330
+ }
331
+ createRequestContext(callType, options) {
332
+ return {
333
+ requestId: uuidv4(),
334
+ actorId: options.headers?.["x-actor-id"] || this.defaultHeaders["x-actor-id"],
335
+ workspaceId: options.headers?.["x-workspace-id"] || this.defaultHeaders["x-workspace-id"],
336
+ startTime: Date.now(),
337
+ callType
338
+ };
339
+ }
340
+ /**
341
+ * Check if an error should be retried
342
+ */
343
+ shouldRetryError(error) {
344
+ if (!(error instanceof GatewayError)) {
345
+ return true;
346
+ }
347
+ return error.type !== GatewayErrorType.GRAPHQL_ERROR && error.type !== GatewayErrorType.CIRCUIT_OPEN;
348
+ }
349
+ /**
350
+ * Calculate retry delay with exponential backoff
351
+ */
352
+ calculateRetryDelay(attempt) {
353
+ return Math.min(this.retryConfig.initialDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt - 1), this.retryConfig.maxDelay);
354
+ }
355
+ /**
356
+ * Log retry attempt if logging is enabled
357
+ */
358
+ logRetryAttempt(context, attempt, maxAttempts, delay, error) {
359
+ if (this.config.enableLogging) {
360
+ logger.warn("[GatewayClient] Request failed, retrying", {
361
+ requestId: context.requestId,
362
+ attempt,
363
+ maxAttempts,
364
+ delay,
365
+ error: error.message
366
+ });
367
+ }
368
+ }
369
+ async executeWithRetry(gatewayUrl, options, circuitBreaker, context, settings) {
370
+ if (!options.skipCircuitBreaker && !circuitBreaker.allowRequest()) {
371
+ throw new GatewayError(`Circuit breaker is open for ${gatewayUrl}`, GatewayErrorType.CIRCUIT_OPEN, gatewayUrl);
372
+ }
373
+ const maxAttempts = options.skipRetry ? 1 : this.retryConfig.maxAttempts;
374
+ let lastError = null;
375
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
376
+ try {
377
+ const result = await this.executeRequest(gatewayUrl, options, context, settings.bypassPermission);
378
+ if (!options.skipCircuitBreaker) {
379
+ circuitBreaker.recordSuccess();
380
+ }
381
+ return result;
382
+ } catch (error) {
383
+ lastError = error instanceof Error ? error : new Error(String(error));
384
+ if (!options.skipCircuitBreaker) {
385
+ circuitBreaker.recordFailure();
386
+ }
387
+ if (!this.shouldRetryError(error)) {
388
+ throw error;
389
+ }
390
+ if (attempt < maxAttempts) {
391
+ const delay = this.calculateRetryDelay(attempt);
392
+ this.logRetryAttempt(context, attempt, maxAttempts, delay, lastError);
393
+ await this.sleep(delay);
394
+ }
395
+ }
396
+ }
397
+ throw lastError || new GatewayError("Request failed after retries", GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);
398
+ }
399
+ /**
400
+ * Build headers for a request
401
+ */
402
+ buildRequestHeaders(context, options, bypassPermission) {
403
+ const headers = {
404
+ "Content-Type": "application/json",
405
+ "x-request-id": context.requestId,
406
+ "x-call-type": context.callType
407
+ };
408
+ for (const [key, value] of Object.entries(this.defaultHeaders)) {
409
+ if (value !== void 0) {
410
+ headers[key] = String(value);
411
+ }
412
+ }
413
+ if (options.headers) {
414
+ for (const [key, value] of Object.entries(options.headers)) {
415
+ if (value !== void 0) {
416
+ headers[key] = String(value);
417
+ }
418
+ }
419
+ }
420
+ if (bypassPermission) {
421
+ headers["x-bypass-permission"] = resolveBypassPermissionValue();
422
+ headers["x-bypass-source"] = this.layerManager.getServiceIdentity();
423
+ headers["x-bypass-timestamp"] = Date.now().toString();
424
+ }
425
+ return headers;
426
+ }
427
+ /**
428
+ * Handle GraphQL errors in response
429
+ */
430
+ handleGraphQLErrors(result, context, gatewayUrl, duration) {
431
+ if (!result.errors || result.errors.length === 0) {
432
+ return;
433
+ }
434
+ const errorMessages = result.errors.map((e) => e.message).join(", ");
435
+ if (this.config.enableLogging) {
436
+ logger.warn("[GatewayClient] GraphQL errors", {
437
+ requestId: context.requestId,
438
+ errors: result.errors,
439
+ duration
440
+ });
441
+ }
442
+ throw new GatewayError(`GraphQL error: ${errorMessages}`, GatewayErrorType.GRAPHQL_ERROR, gatewayUrl, {
443
+ graphqlErrors: result.errors
444
+ });
445
+ }
446
+ /**
447
+ * Handle fetch errors
448
+ */
449
+ handleFetchError(error, context, gatewayUrl, timeout, duration) {
450
+ if (error instanceof GatewayError) {
451
+ throw error;
452
+ }
453
+ if (error instanceof Error) {
454
+ if (error.name === "AbortError") {
455
+ throw new GatewayError(`Request timed out after ${timeout}ms`, GatewayErrorType.TIMEOUT_ERROR, gatewayUrl, {
456
+ cause: error
457
+ });
458
+ }
459
+ if (this.config.enableLogging) {
460
+ logger.error("[GatewayClient] Request failed", {
461
+ requestId: context.requestId,
462
+ error: error.message,
463
+ duration
464
+ });
465
+ }
466
+ throw new GatewayError(error.message, GatewayErrorType.NETWORK_ERROR, gatewayUrl, {
467
+ cause: error
468
+ });
469
+ }
470
+ throw new GatewayError(String(error), GatewayErrorType.UNKNOWN_ERROR, gatewayUrl);
471
+ }
472
+ async executeRequest(gatewayUrl, options, context, bypassPermission) {
473
+ const timeout = options.timeout || this.config.timeout || 3e4;
474
+ const headers = this.buildRequestHeaders(context, options, bypassPermission);
475
+ if (context.callType === "cross-layer" && !hasAuthorizationHeader(headers)) {
476
+ const serviceActorId = this.layerManager.getServiceIdentity();
477
+ const serviceJwt = await signServiceJwt(serviceActorId);
478
+ if (serviceJwt) {
479
+ headers["Authorization"] = `Bearer ${serviceJwt}`;
480
+ } else if (this.config.enableLogging) {
481
+ logger.debug("[GatewayClient] SERVICE_JWT_SECRET not configured \u2014 cross-layer call will proceed without service JWT", {
482
+ requestId: context.requestId,
483
+ gatewayUrl
484
+ });
485
+ }
486
+ }
487
+ const body = JSON.stringify({
488
+ query: options.query,
489
+ variables: options.variables || {},
490
+ operationName: options.operationName
491
+ });
492
+ if (this.config.enableLogging) {
493
+ logger.debug("[GatewayClient] Executing request", {
494
+ requestId: context.requestId,
495
+ gatewayUrl,
496
+ operationName: options.operationName,
497
+ callType: context.callType,
498
+ bypassPermission
499
+ });
500
+ }
501
+ try {
502
+ const controller = new AbortController();
503
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
504
+ const response = await fetch(gatewayUrl, {
505
+ method: "POST",
506
+ headers,
507
+ body,
508
+ signal: controller.signal
509
+ });
510
+ clearTimeout(timeoutId);
511
+ const duration = Date.now() - context.startTime;
512
+ if (!response.ok) {
513
+ throw new GatewayError(`HTTP ${response.status}: ${response.statusText}`, GatewayErrorType.NETWORK_ERROR, gatewayUrl, {
514
+ statusCode: response.status
515
+ });
516
+ }
517
+ const result = await response.json();
518
+ this.handleGraphQLErrors(result, context, gatewayUrl, duration);
519
+ if (this.config.enableLogging) {
520
+ logger.debug("[GatewayClient] Request completed", {
521
+ requestId: context.requestId,
522
+ duration,
523
+ hasData: !!result.data
524
+ });
525
+ }
526
+ return result;
527
+ } catch (error) {
528
+ const duration = Date.now() - context.startTime;
529
+ this.handleFetchError(error, context, gatewayUrl, timeout, duration);
530
+ }
531
+ }
532
+ sleep(ms) {
533
+ return new Promise((resolve) => setTimeout(resolve, ms));
534
+ }
535
+ };
536
+ function createGatewayClient(config) {
537
+ return new GatewayClient(config);
538
+ }
539
+ __name(createGatewayClient, "createGatewayClient");
540
+ function createGatewayClientFromEnv() {
541
+ const layer = process.env["SERVICE_LAYER"];
542
+ if (!layer || layer !== "wspace" && layer !== "global") {
543
+ throw new Error(`[GatewayClient] Invalid or missing SERVICE_LAYER. Expected 'wspace' or 'global', got '${layer}'`);
544
+ }
545
+ const serviceName = process.env["SERVICE_NAME"];
546
+ if (!serviceName) {
547
+ throw new Error("[GatewayClient] SERVICE_NAME environment variable is required");
548
+ }
549
+ const serviceIdentity = process.env["SERVICE_IDENTITY"] || serviceName;
550
+ return new GatewayClient({
551
+ layer,
552
+ serviceName,
553
+ serviceIdentity
554
+ });
555
+ }
556
+ __name(createGatewayClientFromEnv, "createGatewayClientFromEnv");
557
+
558
+ export { CircuitState, GatewayClient, GatewayError, GatewayErrorType, createGatewayClient, createGatewayClientFromEnv, gateway_exports };
559
+ //# sourceMappingURL=chunk-4B43DZIS.js.map
560
+ //# sourceMappingURL=chunk-4B43DZIS.js.map