@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
package/dist/index.js ADDED
@@ -0,0 +1,2626 @@
1
+ export { TemporalClient, TemporalClientFactory, TemporalModule, TemporalWorker, TemporalWorkerFactory, TemporalWorkerManager } from './chunk-Z4IRLBWO.js';
2
+ export { instrumentation_exports as Instrumentation } from './chunk-4XAEES25.js';
3
+ export { middleware_exports as Middleware } from './chunk-2HANKZZM.js';
4
+ export { observability_exports as Observability } from './chunk-5LXDPGDH.js';
5
+ export { prisma_exports as Prisma } from './chunk-2SD5L2F2.js';
6
+ import './chunk-GTEMQXCA.js';
7
+ import { ActivityModule, UsageModule, TrackerModule } from './chunk-JVBTNSPG.js';
8
+ export { ActivityModule, TrackerModule, UsageModule } from './chunk-JVBTNSPG.js';
9
+ import { RBACModule } from './chunk-J26YGR2U.js';
10
+ export { RBACModule, createRBACDirective, createRBACDirectiveForLayer, createRBACDirectiveFromEnv } from './chunk-J26YGR2U.js';
11
+ import { TenantNotificationsModule, NotificationsModule } from './chunk-XC2YD6CF.js';
12
+ export { tenant_notifications_exports as Notifications, NotificationsModule } from './chunk-XC2YD6CF.js';
13
+ export { crypto_exports as Crypto } from './chunk-SBS4S2PJ.js';
14
+ export { createInternalClient, createInternalClientForTenant, createInternalClientForWorkspaces } from './chunk-VI4VSNTI.js';
15
+ export { feature_flags_exports as FeatureFlags } from './chunk-VWCN5PMD.js';
16
+ import { GraphModule } from './chunk-F5XEAGHQ.js';
17
+ export { graph_exports as Graph, GraphModule } from './chunk-F5XEAGHQ.js';
18
+ import './chunk-TKBD2ONF.js';
19
+ export { graphql_exports as GraphQL } from './chunk-MNCGUYLJ.js';
20
+ import './chunk-QLVKMWFA.js';
21
+ export { i18n_exports as I18n, createTranslator, getLanguage, getLocale, hasI18n, t } from './chunk-IYE2NTRX.js';
22
+ export { init_exports as Init } from './chunk-AI7L22ZJ.js';
23
+ import { AuthModule } from './chunk-SAK2JCA7.js';
24
+ export { AuthModule } from './chunk-SAK2JCA7.js';
25
+ export { utils_exports as Utils } from './chunk-MOCUBSTW.js';
26
+ export { cache_exports as Cache } from './chunk-4XGGWW36.js';
27
+ export { captcha_exports as Captcha, isCaptchaEnabled, verifyCaptcha, verifyCaptchaIfEnabled } from './chunk-YMZEUTD2.js';
28
+ export { export_exports as Export } from './chunk-FNZEQOJY.js';
29
+ export { gateway_exports as Gateway } from './chunk-4B43DZIS.js';
30
+ import './chunk-MLW2HPS5.js';
31
+ export { layer_exports as Layer } from './chunk-HIWTWIGQ.js';
32
+ import { EventsModule } from './chunk-M5IMU3US.js';
33
+ export { event_queue_exports as EventQueue, EventsModule } from './chunk-M5IMU3US.js';
34
+ import './chunk-ELLX3K54.js';
35
+ import { EventQueueFactory } from './chunk-3O2RQOPV.js';
36
+ import './chunk-L7ZMN2FJ.js';
37
+ import './chunk-OVSYMNCI.js';
38
+ export { dataloader_exports as DataLoader } from './chunk-NUB5GQTU.js';
39
+ import { DatabaseModule } from './chunk-JG2FTZPI.js';
40
+ export { DatabaseModule } from './chunk-JG2FTZPI.js';
41
+ import { APIError, NetworkError, TimeoutError, ValidationError } from './chunk-SAG6ZYWQ.js';
42
+ export { DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_GATEWAY_RETRY_CONFIG, DEFAULT_GATEWAY_ROUTING, DEFAULT_LAYER_RESOURCES, DEFAULT_LAYER_STREAMS } from './chunk-NGMEI42S.js';
43
+ import { logger } from './chunk-CBZNP6RF.js';
44
+ export { logger_exports as Logger } from './chunk-CBZNP6RF.js';
45
+ import { __name } from './chunk-XE4OXN2W.js';
46
+ import { GraphQLClient } from 'graphql-request';
47
+ import { AsyncLocalStorage } from 'async_hooks';
48
+
49
+ var BurdenoffGraphQLClient = class {
50
+ static {
51
+ __name(this, "BurdenoffGraphQLClient");
52
+ }
53
+ workspacesClient;
54
+ tenantClient;
55
+ config;
56
+ defaultContext;
57
+ constructor(config, defaultContext = {}) {
58
+ this.config = config;
59
+ this.defaultContext = defaultContext;
60
+ this.workspacesClient = new GraphQLClient(config.workspacesApiUrl, {
61
+ headers: this.getHeaders(defaultContext)
62
+ });
63
+ if (config.tenantApiUrl) {
64
+ this.tenantClient = new GraphQLClient(config.tenantApiUrl, {
65
+ headers: this.getHeaders(defaultContext)
66
+ });
67
+ }
68
+ }
69
+ /**
70
+ * Get headers for GraphQL request
71
+ * Includes actor context headers for RBAC authorization
72
+ */
73
+ getHeaders(context) {
74
+ const headers = {
75
+ "Content-Type": "application/json"
76
+ };
77
+ if (context.token) {
78
+ headers["Authorization"] = `Bearer ${context.token}`;
79
+ }
80
+ if (context.actorId) {
81
+ headers["x-actor-id"] = context.actorId;
82
+ }
83
+ if (context.actorType) {
84
+ headers["x-actor-type"] = context.actorType;
85
+ }
86
+ if (context.workspaceId) {
87
+ headers["x-workspace-id"] = context.workspaceId;
88
+ }
89
+ if (context.productId) {
90
+ headers["x-product-id"] = context.productId;
91
+ }
92
+ return headers;
93
+ }
94
+ /**
95
+ * Update context for future requests
96
+ */
97
+ updateContext(context) {
98
+ this.defaultContext = {
99
+ ...this.defaultContext,
100
+ ...context
101
+ };
102
+ this.workspacesClient.setHeaders(this.getHeaders(this.defaultContext));
103
+ if (this.tenantClient) {
104
+ this.tenantClient.setHeaders(this.getHeaders(this.defaultContext));
105
+ }
106
+ }
107
+ /**
108
+ * Execute GraphQL query/mutation against workspaces API
109
+ */
110
+ async query(query, variables, context) {
111
+ return this.executeWithRetry(() => this.executeQuery(this.workspacesClient, query, variables, context), "workspaces");
112
+ }
113
+ /**
114
+ * Execute GraphQL query/mutation against tenant API
115
+ */
116
+ async tenantQuery(query, variables, context) {
117
+ if (!this.tenantClient) {
118
+ throw new APIError("Tenant API URL not configured", {
119
+ operation: "tenantQuery"
120
+ });
121
+ }
122
+ return this.executeWithRetry(() => this.executeQuery(this.tenantClient, query, variables, context), "tenant");
123
+ }
124
+ /**
125
+ * Execute GraphQL request
126
+ */
127
+ async executeQuery(client, query, variables, context) {
128
+ try {
129
+ const mergedContext = {
130
+ ...this.defaultContext,
131
+ ...context
132
+ };
133
+ if (context) {
134
+ const headers = this.getHeaders(mergedContext);
135
+ client.setHeaders(headers);
136
+ }
137
+ const response = await client.request(query, variables);
138
+ return response;
139
+ } catch (error) {
140
+ throw this.handleError(error);
141
+ }
142
+ }
143
+ /**
144
+ * Execute with retry logic
145
+ */
146
+ async executeWithRetry(operation, api) {
147
+ const maxAttempts = this.config.retry?.maxAttempts || 3;
148
+ const initialDelay = this.config.retry?.initialDelay || 1e3;
149
+ const maxDelay = this.config.retry?.maxDelay || 1e4;
150
+ const backoffMultiplier = this.config.retry?.backoffMultiplier || 2;
151
+ let lastError;
152
+ let delay = initialDelay;
153
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
154
+ try {
155
+ return await operation();
156
+ } catch (error) {
157
+ lastError = error;
158
+ if (error instanceof APIError && !this.shouldRetry(error)) {
159
+ throw error;
160
+ }
161
+ if (attempt === maxAttempts) {
162
+ break;
163
+ }
164
+ await this.sleep(Math.min(delay, maxDelay));
165
+ delay *= backoffMultiplier;
166
+ }
167
+ }
168
+ throw new APIError(`GraphQL request failed after ${maxAttempts} attempts`, {
169
+ api,
170
+ lastError: lastError?.message
171
+ });
172
+ }
173
+ /**
174
+ * Determine if error should be retried
175
+ */
176
+ shouldRetry(error) {
177
+ if (error instanceof NetworkError || error instanceof TimeoutError) {
178
+ return true;
179
+ }
180
+ if (error.code === "SERVER_ERROR") {
181
+ return true;
182
+ }
183
+ return false;
184
+ }
185
+ /**
186
+ * Handle GraphQL errors
187
+ */
188
+ handleError(error) {
189
+ if (error instanceof Error) {
190
+ if (error.message.includes("fetch failed") || error.message.includes("ECONNREFUSED")) {
191
+ return new NetworkError("Network error while connecting to API", {
192
+ originalError: error.message
193
+ });
194
+ }
195
+ if (error.message.includes("timeout") || error.message.includes("ETIMEDOUT")) {
196
+ return new TimeoutError("Request timed out", {
197
+ originalError: error.message
198
+ });
199
+ }
200
+ if ("response" in error && error.response) {
201
+ const response = error.response;
202
+ if (response.errors && response.errors.length > 0) {
203
+ const firstError = response.errors[0];
204
+ if (firstError) {
205
+ return new APIError(firstError.message, {
206
+ graphqlErrors: response.errors,
207
+ extensions: firstError.extensions
208
+ });
209
+ }
210
+ }
211
+ }
212
+ return new APIError(error.message, {
213
+ originalError: error.message
214
+ });
215
+ }
216
+ return new APIError("Unknown error occurred", {
217
+ error: String(error)
218
+ });
219
+ }
220
+ /**
221
+ * Sleep utility for retry delays
222
+ */
223
+ sleep(ms) {
224
+ return new Promise((resolve) => setTimeout(resolve, ms));
225
+ }
226
+ /**
227
+ * Get current context
228
+ */
229
+ getContext() {
230
+ return {
231
+ ...this.defaultContext
232
+ };
233
+ }
234
+ };
235
+ var asyncLocalStorage = new AsyncLocalStorage();
236
+ var ContextManager = class {
237
+ static {
238
+ __name(this, "ContextManager");
239
+ }
240
+ /**
241
+ * Get current context from async local storage
242
+ */
243
+ static getContext() {
244
+ return asyncLocalStorage.getStore();
245
+ }
246
+ /**
247
+ * Set context for current async scope
248
+ * Merges with existing context if present
249
+ */
250
+ static setContext(context) {
251
+ const currentContext = this.getContext() || {};
252
+ asyncLocalStorage.enterWith({
253
+ ...currentContext,
254
+ ...context
255
+ });
256
+ }
257
+ /**
258
+ * Run function with specific context
259
+ * Context is isolated to this execution and its children
260
+ */
261
+ static async withContext(context, fn) {
262
+ return asyncLocalStorage.run(context, fn);
263
+ }
264
+ /**
265
+ * Run synchronous function with specific context
266
+ */
267
+ static withContextSync(context, fn) {
268
+ return asyncLocalStorage.run(context, fn);
269
+ }
270
+ /**
271
+ * Clear current context
272
+ */
273
+ static clearContext() {
274
+ asyncLocalStorage.disable();
275
+ }
276
+ /**
277
+ * Get actor ID from context
278
+ */
279
+ static getActorId() {
280
+ return this.getContext()?.actorId;
281
+ }
282
+ /**
283
+ * Get legacy user ID from context.
284
+ */
285
+ static getUser() {
286
+ const context = this.getContext();
287
+ const userId = context?.["userId"];
288
+ return typeof userId === "string" ? userId : context?.actorId;
289
+ }
290
+ /**
291
+ * Get workspace ID from context
292
+ */
293
+ static getWorkspace() {
294
+ return this.getContext()?.workspaceId;
295
+ }
296
+ /**
297
+ * Get tenant ID from context
298
+ */
299
+ static getTenant() {
300
+ return this.getContext()?.tenantId;
301
+ }
302
+ /**
303
+ * Get legacy organization ID from context.
304
+ */
305
+ static getOrganization() {
306
+ const organizationId = this.getContext()?.["organizationId"];
307
+ return typeof organizationId === "string" ? organizationId : void 0;
308
+ }
309
+ /**
310
+ * Get project ID from context
311
+ */
312
+ static getProject() {
313
+ return this.getContext()?.projectId;
314
+ }
315
+ /**
316
+ * Get app ID from context
317
+ */
318
+ static getApp() {
319
+ return this.getContext()?.appId;
320
+ }
321
+ /**
322
+ * Get JWT token from context
323
+ */
324
+ static getToken() {
325
+ return this.getContext()?.token;
326
+ }
327
+ /**
328
+ * Get product ID from context
329
+ */
330
+ static getProduct() {
331
+ return this.getContext()?.productId;
332
+ }
333
+ /**
334
+ * Update specific context fields
335
+ */
336
+ static updateContext(updates) {
337
+ const current = this.getContext();
338
+ if (current) {
339
+ this.setContext({
340
+ ...current,
341
+ ...updates
342
+ });
343
+ } else {
344
+ this.setContext(updates);
345
+ }
346
+ }
347
+ /**
348
+ * Check if context exists
349
+ */
350
+ static hasContext() {
351
+ return this.getContext() !== void 0;
352
+ }
353
+ /**
354
+ * Get custom field from context
355
+ */
356
+ static getCustomField(key) {
357
+ return this.getContext()?.[key];
358
+ }
359
+ /**
360
+ * Set custom field in context
361
+ */
362
+ static setCustomField(key, value) {
363
+ const current = this.getContext() || {};
364
+ this.setContext({
365
+ ...current,
366
+ [key]: value
367
+ });
368
+ }
369
+ };
370
+
371
+ // src/search/index.ts
372
+ var SearchModule = class {
373
+ static {
374
+ __name(this, "SearchModule");
375
+ }
376
+ client;
377
+ context;
378
+ constructor(client, context) {
379
+ this.client = client;
380
+ this.context = context;
381
+ }
382
+ /**
383
+ * Search across all resources
384
+ */
385
+ async search(options) {
386
+ if (!options.query || options.query.trim().length === 0) {
387
+ throw new ValidationError("Search query is required");
388
+ }
389
+ logger.debug("[Search] Searching", {
390
+ query: options.query,
391
+ resourceTypes: options.resourceTypes
392
+ });
393
+ const query = `
394
+ query Search($input: SearchInput!) {
395
+ search(input: $input) {
396
+ results {
397
+ id
398
+ type
399
+ title
400
+ description
401
+ data
402
+ workspaceId
403
+ organizationId
404
+ projectId
405
+ score
406
+ highlights
407
+ createdAt
408
+ updatedAt
409
+ }
410
+ total
411
+ took
412
+ aggregations
413
+ }
414
+ }
415
+ `;
416
+ const variables = {
417
+ input: {
418
+ query: options.query,
419
+ resourceTypes: options.resourceTypes,
420
+ workspaceId: options.workspaceId || this.context.workspaceId,
421
+ organizationId: options.organizationId,
422
+ projectId: options.projectId || this.context.projectId,
423
+ fields: options.fields,
424
+ fuzziness: options.fuzziness || 0.8,
425
+ boosts: options.boosts,
426
+ filters: options.filters,
427
+ sort: options.sort,
428
+ limit: options.limit || 20,
429
+ offset: options.offset || 0,
430
+ highlight: options.highlight !== false
431
+ }
432
+ };
433
+ const response = await this.client.query(query, variables, this.context);
434
+ logger.info("[Search] Search completed", {
435
+ total: response.search.total,
436
+ took: response.search.took
437
+ });
438
+ return response.search;
439
+ }
440
+ /**
441
+ * Index document for search
442
+ */
443
+ async indexDocument(options) {
444
+ if (!options.id) {
445
+ throw new ValidationError("Document ID is required");
446
+ }
447
+ if (!options.type) {
448
+ throw new ValidationError("Document type is required");
449
+ }
450
+ if (!options.title) {
451
+ throw new ValidationError("Document title is required");
452
+ }
453
+ logger.debug("[Search] Indexing document", {
454
+ id: options.id,
455
+ type: options.type
456
+ });
457
+ const mutation = `
458
+ mutation IndexDocument($input: IndexDocumentInput!) {
459
+ indexDocument(input: $input) {
460
+ id
461
+ indexed
462
+ }
463
+ }
464
+ `;
465
+ const variables = {
466
+ input: {
467
+ id: options.id,
468
+ type: options.type,
469
+ title: options.title,
470
+ description: options.description,
471
+ content: options.content,
472
+ data: options.data,
473
+ workspaceId: options.workspaceId || this.context.workspaceId,
474
+ organizationId: options.organizationId,
475
+ projectId: options.projectId || this.context.projectId,
476
+ tags: options.tags,
477
+ metadata: options.metadata
478
+ }
479
+ };
480
+ const response = await this.client.query(mutation, variables, this.context);
481
+ logger.info("[Search] Document indexed", {
482
+ id: response.indexDocument.id
483
+ });
484
+ return response.indexDocument;
485
+ }
486
+ /**
487
+ * Remove document from search index
488
+ */
489
+ async removeDocument(id, type) {
490
+ logger.debug("[Search] Removing document", {
491
+ id,
492
+ type
493
+ });
494
+ const mutation = `
495
+ mutation RemoveDocument($id: ID!, $type: String!) {
496
+ removeDocument(id: $id, type: $type) {
497
+ success
498
+ }
499
+ }
500
+ `;
501
+ await this.client.query(mutation, {
502
+ id,
503
+ type
504
+ }, this.context);
505
+ logger.info("[Search] Document removed", {
506
+ id
507
+ });
508
+ return true;
509
+ }
510
+ /**
511
+ * Update document in search index
512
+ */
513
+ async updateDocument(id, type, updates) {
514
+ logger.debug("[Search] Updating document", {
515
+ id,
516
+ type
517
+ });
518
+ const mutation = `
519
+ mutation UpdateDocument($id: ID!, $type: String!, $updates: JSON!) {
520
+ updateDocument(id: $id, type: $type, updates: $updates) {
521
+ id
522
+ updated
523
+ }
524
+ }
525
+ `;
526
+ const response = await this.client.query(mutation, {
527
+ id,
528
+ type,
529
+ updates
530
+ }, this.context);
531
+ logger.info("[Search] Document updated", {
532
+ id
533
+ });
534
+ return response.updateDocument;
535
+ }
536
+ /**
537
+ * Bulk index documents
538
+ */
539
+ async indexDocumentsBulk(documents) {
540
+ logger.debug("[Search] Bulk indexing documents", {
541
+ count: documents.length
542
+ });
543
+ const mutation = `
544
+ mutation IndexDocumentsBulk($documents: [IndexDocumentInput!]!) {
545
+ indexDocumentsBulk(documents: $documents) {
546
+ indexed
547
+ failed
548
+ errors
549
+ }
550
+ }
551
+ `;
552
+ const response = await this.client.query(mutation, {
553
+ documents
554
+ }, this.context);
555
+ logger.info("[Search] Bulk indexing completed", {
556
+ indexed: response.indexDocumentsBulk.indexed,
557
+ failed: response.indexDocumentsBulk.failed
558
+ });
559
+ return response.indexDocumentsBulk;
560
+ }
561
+ /**
562
+ * Get search suggestions (autocomplete)
563
+ */
564
+ async suggest(prefix, options) {
565
+ if (!prefix || prefix.trim().length === 0) {
566
+ throw new ValidationError("Prefix is required for suggestions");
567
+ }
568
+ logger.debug("[Search] Getting suggestions", {
569
+ prefix
570
+ });
571
+ const query = `
572
+ query GetSuggestions($prefix: String!, $resourceTypes: [String!], $limit: Int) {
573
+ getSuggestions(prefix: $prefix, resourceTypes: $resourceTypes, limit: $limit) {
574
+ text
575
+ score
576
+ type
577
+ }
578
+ }
579
+ `;
580
+ const response = await this.client.query(query, {
581
+ prefix,
582
+ resourceTypes: options?.resourceTypes,
583
+ limit: options?.limit || 10
584
+ }, this.context);
585
+ return response.getSuggestions;
586
+ }
587
+ /**
588
+ * Get related documents
589
+ */
590
+ async getRelated(documentId, options) {
591
+ logger.debug("[Search] Getting related documents", {
592
+ documentId
593
+ });
594
+ const query = `
595
+ query GetRelatedDocuments($documentId: ID!, $limit: Int, $minScore: Float) {
596
+ getRelatedDocuments(documentId: $documentId, limit: $limit, minScore: $minScore) {
597
+ id
598
+ type
599
+ title
600
+ description
601
+ data
602
+ score
603
+ createdAt
604
+ updatedAt
605
+ }
606
+ }
607
+ `;
608
+ const response = await this.client.query(query, {
609
+ documentId,
610
+ limit: options?.limit || 10,
611
+ minScore: options?.minScore || 0.5
612
+ }, this.context);
613
+ return response.getRelatedDocuments;
614
+ }
615
+ /**
616
+ * Get search aggregations
617
+ */
618
+ async aggregate(query, aggregations) {
619
+ logger.debug("[Search] Getting aggregations", {
620
+ query
621
+ });
622
+ const gqlQuery = `
623
+ query GetAggregations($query: String!, $aggregations: [AggregationInput!]!) {
624
+ getAggregations(query: $query, aggregations: $aggregations) {
625
+ aggregations
626
+ }
627
+ }
628
+ `;
629
+ const response = await this.client.query(gqlQuery, {
630
+ query,
631
+ aggregations
632
+ }, this.context);
633
+ return response.getAggregations.aggregations;
634
+ }
635
+ /**
636
+ * Clear search index for workspace
637
+ */
638
+ async clearIndex(workspaceId) {
639
+ logger.debug("[Search] Clearing index", {
640
+ workspaceId
641
+ });
642
+ const mutation = `
643
+ mutation ClearSearchIndex($workspaceId: ID) {
644
+ clearSearchIndex(workspaceId: $workspaceId) {
645
+ deletedCount
646
+ }
647
+ }
648
+ `;
649
+ const response = await this.client.query(mutation, {
650
+ workspaceId: workspaceId || this.context.workspaceId
651
+ }, this.context);
652
+ logger.info("[Search] Index cleared", {
653
+ deletedCount: response.clearSearchIndex.deletedCount
654
+ });
655
+ return response.clearSearchIndex;
656
+ }
657
+ /**
658
+ * Reindex all documents
659
+ */
660
+ async reindex(options) {
661
+ logger.debug("[Search] Reindexing", options);
662
+ const mutation = `
663
+ mutation ReindexDocuments($workspaceId: ID, $resourceTypes: [String!]) {
664
+ reindexDocuments(workspaceId: $workspaceId, resourceTypes: $resourceTypes) {
665
+ indexed
666
+ failed
667
+ }
668
+ }
669
+ `;
670
+ const response = await this.client.query(mutation, {
671
+ workspaceId: options?.workspaceId || this.context.workspaceId,
672
+ resourceTypes: options?.resourceTypes
673
+ }, this.context);
674
+ logger.info("[Search] Reindexing completed", response.reindexDocuments);
675
+ return response.reindexDocuments;
676
+ }
677
+ };
678
+
679
+ // src/translation/index.ts
680
+ var TranslationModule = class {
681
+ static {
682
+ __name(this, "TranslationModule");
683
+ }
684
+ client;
685
+ context;
686
+ constructor(client, context) {
687
+ this.client = client;
688
+ this.context = context;
689
+ }
690
+ /**
691
+ * Translate text
692
+ */
693
+ async translate(options) {
694
+ if (!options.text || options.text.trim().length === 0) {
695
+ throw new ValidationError("Text to translate is required");
696
+ }
697
+ if (!options.targetLanguage) {
698
+ throw new ValidationError("Target language is required");
699
+ }
700
+ logger.debug("[Translation] Translating text", {
701
+ sourceLanguage: options.sourceLanguage || "auto",
702
+ targetLanguage: options.targetLanguage,
703
+ textLength: options.text.length
704
+ });
705
+ const query = `
706
+ query Translate($input: TranslateInput!) {
707
+ translate(input: $input) {
708
+ original
709
+ translated
710
+ sourceLanguage
711
+ targetLanguage
712
+ confidence
713
+ }
714
+ }
715
+ `;
716
+ const variables = {
717
+ input: {
718
+ text: options.text,
719
+ sourceLanguage: options.sourceLanguage,
720
+ targetLanguage: options.targetLanguage,
721
+ context: options.context
722
+ }
723
+ };
724
+ const response = await this.client.query(query, variables, this.context);
725
+ let translated = response.translate.translated;
726
+ if (options.variables) {
727
+ translated = this.interpolate(translated, options.variables);
728
+ }
729
+ logger.info("[Translation] Text translated", {
730
+ sourceLanguage: response.translate.sourceLanguage,
731
+ targetLanguage: response.translate.targetLanguage
732
+ });
733
+ return {
734
+ ...response.translate,
735
+ translated
736
+ };
737
+ }
738
+ /**
739
+ * Get translations for keys
740
+ */
741
+ async getTranslations(options) {
742
+ if (!options.keys || options.keys.length === 0) {
743
+ throw new ValidationError("Translation keys are required");
744
+ }
745
+ if (!options.language) {
746
+ throw new ValidationError("Language is required");
747
+ }
748
+ logger.debug("[Translation] Getting translations", {
749
+ language: options.language,
750
+ count: options.keys.length
751
+ });
752
+ const query = `
753
+ query GetTranslations(
754
+ $keys: [String!]!
755
+ $language: String!
756
+ $namespace: String
757
+ $fallbackLanguage: String
758
+ ) {
759
+ getTranslations(
760
+ keys: $keys
761
+ language: $language
762
+ namespace: $namespace
763
+ fallbackLanguage: $fallbackLanguage
764
+ ) {
765
+ translations
766
+ }
767
+ }
768
+ `;
769
+ const response = await this.client.query(query, {
770
+ keys: options.keys,
771
+ language: options.language,
772
+ namespace: options.namespace,
773
+ fallbackLanguage: options.fallbackLanguage || "en"
774
+ }, this.context);
775
+ return response.getTranslations.translations;
776
+ }
777
+ /**
778
+ * Get single translation
779
+ */
780
+ async get(key, language, variables) {
781
+ const translations = await this.getTranslations({
782
+ keys: [
783
+ key
784
+ ],
785
+ language
786
+ });
787
+ let translation = translations[key] || key;
788
+ if (variables) {
789
+ translation = this.interpolate(translation, variables);
790
+ }
791
+ return translation;
792
+ }
793
+ /**
794
+ * Set translation
795
+ */
796
+ async setTranslation(options) {
797
+ if (!options.key) {
798
+ throw new ValidationError("Translation key is required");
799
+ }
800
+ if (!options.value) {
801
+ throw new ValidationError("Translation value is required");
802
+ }
803
+ if (!options.language) {
804
+ throw new ValidationError("Language is required");
805
+ }
806
+ logger.debug("[Translation] Setting translation", {
807
+ key: options.key,
808
+ language: options.language
809
+ });
810
+ const mutation = `
811
+ mutation SetTranslation($input: SetTranslationInput!) {
812
+ setTranslation(input: $input) {
813
+ key
814
+ value
815
+ language
816
+ namespace
817
+ description
818
+ variables
819
+ }
820
+ }
821
+ `;
822
+ const variables = {
823
+ input: {
824
+ key: options.key,
825
+ value: options.value,
826
+ language: options.language,
827
+ namespace: options.namespace,
828
+ description: options.description,
829
+ variables: options.variables
830
+ }
831
+ };
832
+ const response = await this.client.query(mutation, variables, this.context);
833
+ logger.info("[Translation] Translation set", {
834
+ key: options.key,
835
+ language: options.language
836
+ });
837
+ return response.setTranslation;
838
+ }
839
+ /**
840
+ * Delete translation
841
+ */
842
+ async deleteTranslation(key, language, namespace) {
843
+ logger.debug("[Translation] Deleting translation", {
844
+ key,
845
+ language
846
+ });
847
+ const mutation = `
848
+ mutation DeleteTranslation($key: String!, $language: String!, $namespace: String) {
849
+ deleteTranslation(key: $key, language: $language, namespace: $namespace) {
850
+ success
851
+ }
852
+ }
853
+ `;
854
+ await this.client.query(mutation, {
855
+ key,
856
+ language,
857
+ namespace
858
+ }, this.context);
859
+ logger.info("[Translation] Translation deleted", {
860
+ key,
861
+ language
862
+ });
863
+ return true;
864
+ }
865
+ /**
866
+ * Batch set translations
867
+ */
868
+ async setTranslationsBatch(translations) {
869
+ logger.debug("[Translation] Batch setting translations", {
870
+ count: translations.length
871
+ });
872
+ const mutation = `
873
+ mutation SetTranslationsBatch($translations: [SetTranslationInput!]!) {
874
+ setTranslationsBatch(translations: $translations) {
875
+ key
876
+ value
877
+ language
878
+ namespace
879
+ description
880
+ variables
881
+ }
882
+ }
883
+ `;
884
+ const response = await this.client.query(mutation, {
885
+ translations
886
+ }, this.context);
887
+ logger.info("[Translation] Batch translations set", {
888
+ count: response.setTranslationsBatch.length
889
+ });
890
+ return response.setTranslationsBatch;
891
+ }
892
+ /**
893
+ * Get all translations for language
894
+ */
895
+ async getAllTranslations(language, namespace) {
896
+ logger.debug("[Translation] Getting all translations", {
897
+ language,
898
+ namespace
899
+ });
900
+ const query = `
901
+ query GetAllTranslations($language: String!, $namespace: String) {
902
+ getAllTranslations(language: $language, namespace: $namespace) {
903
+ key
904
+ value
905
+ language
906
+ namespace
907
+ description
908
+ variables
909
+ }
910
+ }
911
+ `;
912
+ const response = await this.client.query(query, {
913
+ language,
914
+ namespace
915
+ }, this.context);
916
+ return response.getAllTranslations;
917
+ }
918
+ /**
919
+ * Detect language
920
+ */
921
+ async detectLanguage(text) {
922
+ if (!text || text.trim().length === 0) {
923
+ throw new ValidationError("Text is required for language detection");
924
+ }
925
+ logger.debug("[Translation] Detecting language");
926
+ const query = `
927
+ query DetectLanguage($text: String!) {
928
+ detectLanguage(text: $text) {
929
+ language
930
+ confidence
931
+ }
932
+ }
933
+ `;
934
+ const response = await this.client.query(query, {
935
+ text
936
+ }, this.context);
937
+ return response.detectLanguage;
938
+ }
939
+ /**
940
+ * Get supported languages
941
+ */
942
+ async getSupportedLanguages() {
943
+ logger.debug("[Translation] Getting supported languages");
944
+ const query = `
945
+ query GetSupportedLanguages {
946
+ getSupportedLanguages {
947
+ code
948
+ name
949
+ nativeName
950
+ }
951
+ }
952
+ `;
953
+ const response = await this.client.query(query, {}, this.context);
954
+ return response.getSupportedLanguages;
955
+ }
956
+ /**
957
+ * Import translations from file
958
+ */
959
+ async importTranslations(language, translations, namespace) {
960
+ logger.debug("[Translation] Importing translations", {
961
+ language,
962
+ count: Object.keys(translations).length
963
+ });
964
+ const mutation = `
965
+ mutation ImportTranslations($language: String!, $translations: JSON!, $namespace: String) {
966
+ importTranslations(language: $language, translations: $translations, namespace: $namespace) {
967
+ imported
968
+ failed
969
+ }
970
+ }
971
+ `;
972
+ const response = await this.client.query(mutation, {
973
+ language,
974
+ translations,
975
+ namespace
976
+ }, this.context);
977
+ logger.info("[Translation] Translations imported", response.importTranslations);
978
+ return response.importTranslations;
979
+ }
980
+ /**
981
+ * Export translations to JSON
982
+ */
983
+ async exportTranslations(language, namespace) {
984
+ logger.debug("[Translation] Exporting translations", {
985
+ language,
986
+ namespace
987
+ });
988
+ const query = `
989
+ query ExportTranslations($language: String!, $namespace: String) {
990
+ exportTranslations(language: $language, namespace: $namespace) {
991
+ translations
992
+ }
993
+ }
994
+ `;
995
+ const response = await this.client.query(query, {
996
+ language,
997
+ namespace
998
+ }, this.context);
999
+ logger.info("[Translation] Translations exported", {
1000
+ language,
1001
+ count: Object.keys(response.exportTranslations.translations).length
1002
+ });
1003
+ return response.exportTranslations.translations;
1004
+ }
1005
+ /**
1006
+ * Export product translations from global i18n service (federated schema).
1007
+ *
1008
+ * This uses the modern i18n GraphQL contract:
1009
+ * - i18nProductByName
1010
+ * - exportTranslations(productId, languageCode, format)
1011
+ */
1012
+ async exportProductTranslations(options) {
1013
+ const productId = await this.resolveProductId(options.productId, options.productName);
1014
+ const languageCode = options.languageCode ?? "en";
1015
+ const format = options.format ?? "JSON";
1016
+ const query = `
1017
+ query ExportProductTranslations(
1018
+ $productId: String!
1019
+ $languageCode: String!
1020
+ $format: ImportJobFormat!
1021
+ ) {
1022
+ exportTranslations(productId: $productId, languageCode: $languageCode, format: $format) {
1023
+ format
1024
+ url
1025
+ }
1026
+ }
1027
+ `;
1028
+ const response = await this.client.query(query, {
1029
+ productId,
1030
+ languageCode,
1031
+ format
1032
+ }, this.context);
1033
+ const result = {
1034
+ format: response.exportTranslations.format,
1035
+ url: response.exportTranslations.url
1036
+ };
1037
+ if ((options.decodeJson ?? true) && format === "JSON") {
1038
+ result.translations = this.decodeDataUrlJson(response.exportTranslations.url);
1039
+ }
1040
+ return result;
1041
+ }
1042
+ /**
1043
+ * Upsert product translations in global i18n service.
1044
+ *
1045
+ * Behavior:
1046
+ * - Ensures translation keys exist (create if missing)
1047
+ * - Optionally updates translation key defaultValue
1048
+ * - Creates/updates language translation entries
1049
+ * - Optionally publishes translations
1050
+ */
1051
+ async upsertProductTranslations(options) {
1052
+ if (!options.languageCode) {
1053
+ throw new ValidationError("languageCode is required");
1054
+ }
1055
+ const flatTranslations = this.flattenTranslationTree(options.translations);
1056
+ if (Object.keys(flatTranslations).length === 0) {
1057
+ throw new ValidationError("translations cannot be empty");
1058
+ }
1059
+ const flatDefaults = options.defaultValues ? this.flattenTranslationTree(options.defaultValues) : flatTranslations;
1060
+ const productId = await this.resolveProductId(options.productId, options.productName);
1061
+ const publish = options.publish ?? true;
1062
+ const updateExisting = options.updateExisting ?? true;
1063
+ const result = {
1064
+ productId,
1065
+ languageCode: options.languageCode,
1066
+ keysProcessed: 0,
1067
+ createdKeys: 0,
1068
+ updatedKeyDefaults: 0,
1069
+ createdTranslations: 0,
1070
+ updatedTranslations: 0
1071
+ };
1072
+ const entries = Object.entries(flatTranslations);
1073
+ const existingKeysMap = /* @__PURE__ */ new Map();
1074
+ for (const [key] of entries) {
1075
+ const keyRow = await this.findTranslationKeyByKey(productId, key);
1076
+ if (keyRow) {
1077
+ existingKeysMap.set(key, keyRow);
1078
+ }
1079
+ }
1080
+ for (const [key, value] of entries) {
1081
+ const defaultValue = flatDefaults[key] ?? value;
1082
+ let keyId = "";
1083
+ const keyRow = existingKeysMap.get(key);
1084
+ if (!keyRow) {
1085
+ const createdKey = await this.createTranslationKey(productId, key, defaultValue);
1086
+ keyId = createdKey.id;
1087
+ result.createdKeys += 1;
1088
+ } else {
1089
+ keyId = keyRow.id;
1090
+ if (defaultValue && keyRow.defaultValue !== defaultValue) {
1091
+ await this.updateTranslationKeyDefaultValue(keyId, defaultValue);
1092
+ result.updatedKeyDefaults += 1;
1093
+ }
1094
+ }
1095
+ const translationRow = await this.findGlobalTranslation(keyId, options.languageCode);
1096
+ if (!translationRow) {
1097
+ const createdTranslation = await this.createLanguageTranslation(keyId, options.languageCode, value);
1098
+ result.createdTranslations += 1;
1099
+ if (publish && createdTranslation.status !== "PUBLISHED") {
1100
+ await this.updateLanguageTranslation(createdTranslation.id, value, "PUBLISHED");
1101
+ }
1102
+ } else {
1103
+ const shouldUpdateValue = updateExisting && translationRow.value !== value;
1104
+ const shouldPublish = publish && translationRow.status !== "PUBLISHED";
1105
+ if (shouldUpdateValue || shouldPublish) {
1106
+ await this.updateLanguageTranslation(translationRow.id, shouldUpdateValue ? value : translationRow.value, publish ? "PUBLISHED" : translationRow.status);
1107
+ if (shouldUpdateValue) {
1108
+ result.updatedTranslations += 1;
1109
+ }
1110
+ }
1111
+ }
1112
+ result.keysProcessed += 1;
1113
+ }
1114
+ logger.info("[Translation] Product translations upsert completed", {
1115
+ productId,
1116
+ languageCode: options.languageCode,
1117
+ keysProcessed: result.keysProcessed,
1118
+ createdKeys: result.createdKeys,
1119
+ createdTranslations: result.createdTranslations,
1120
+ updatedTranslations: result.updatedTranslations
1121
+ });
1122
+ return result;
1123
+ }
1124
+ flattenTranslationTree(input, prefix = "") {
1125
+ const out = {};
1126
+ for (const [key, rawValue] of Object.entries(input)) {
1127
+ const nextKey = prefix ? `${prefix}.${key}` : key;
1128
+ if (typeof rawValue === "string") {
1129
+ out[nextKey] = rawValue;
1130
+ continue;
1131
+ }
1132
+ if (rawValue && typeof rawValue === "object") {
1133
+ Object.assign(out, this.flattenTranslationTree(rawValue, nextKey));
1134
+ }
1135
+ }
1136
+ return out;
1137
+ }
1138
+ decodeDataUrlJson(url) {
1139
+ if (!url.startsWith("data:")) {
1140
+ throw new ValidationError("Expected exportTranslations URL to be a data URL");
1141
+ }
1142
+ const commaIdx = url.indexOf(",");
1143
+ if (commaIdx === -1) {
1144
+ throw new ValidationError("Invalid data URL: missing comma separator");
1145
+ }
1146
+ const header = url.slice(0, commaIdx);
1147
+ const payload = url.slice(commaIdx + 1);
1148
+ if (!payload) {
1149
+ throw new ValidationError("Invalid data URL payload");
1150
+ }
1151
+ try {
1152
+ const decoded = header.includes("base64") ? Buffer.from(payload, "base64").toString("utf8") : decodeURIComponent(payload);
1153
+ return JSON.parse(decoded);
1154
+ } catch (error) {
1155
+ logger.error("[Translation] Failed to decode data URL JSON", {
1156
+ error,
1157
+ isBase64: header.includes("base64")
1158
+ });
1159
+ throw new ValidationError("Failed to decode JSON translation payload");
1160
+ }
1161
+ }
1162
+ async resolveProductId(productId, productName) {
1163
+ if (productId) {
1164
+ return productId;
1165
+ }
1166
+ if (!productName) {
1167
+ throw new ValidationError("Either productId or productName is required");
1168
+ }
1169
+ const query = `
1170
+ query GetI18nProductByName($name: String!) {
1171
+ i18nProductByName(name: $name) {
1172
+ id
1173
+ }
1174
+ }
1175
+ `;
1176
+ const response = await this.client.query(query, {
1177
+ name: productName
1178
+ }, this.context);
1179
+ if (!response.i18nProductByName?.id) {
1180
+ throw new ValidationError(`i18n product not found: ${productName}`);
1181
+ }
1182
+ return response.i18nProductByName.id;
1183
+ }
1184
+ async findTranslationKeyByKey(productId, key) {
1185
+ const query = `
1186
+ query FindTranslationKey($productId: String!, $key: String!) {
1187
+ translationKeyByKey(productId: $productId, key: $key) {
1188
+ id
1189
+ defaultValue
1190
+ }
1191
+ }
1192
+ `;
1193
+ const response = await this.client.query(query, {
1194
+ productId,
1195
+ key
1196
+ }, this.context);
1197
+ return response.translationKeyByKey;
1198
+ }
1199
+ async createTranslationKey(productId, key, defaultValue) {
1200
+ const mutation = `
1201
+ mutation CreateTranslationKey($input: CreateTranslationKeyInput!) {
1202
+ createTranslationKey(input: $input) {
1203
+ id
1204
+ }
1205
+ }
1206
+ `;
1207
+ const response = await this.client.query(mutation, {
1208
+ input: {
1209
+ productId,
1210
+ key,
1211
+ defaultValue
1212
+ }
1213
+ }, this.context);
1214
+ return response.createTranslationKey;
1215
+ }
1216
+ async updateTranslationKeyDefaultValue(id, defaultValue) {
1217
+ const mutation = `
1218
+ mutation UpdateTranslationKeyDefault($id: ID!, $input: UpdateTranslationKeyInput!) {
1219
+ updateTranslationKey(id: $id, input: $input) {
1220
+ id
1221
+ }
1222
+ }
1223
+ `;
1224
+ await this.client.query(mutation, {
1225
+ id,
1226
+ input: {
1227
+ defaultValue
1228
+ }
1229
+ }, this.context);
1230
+ }
1231
+ async findGlobalTranslation(keyId, languageCode) {
1232
+ const query = `
1233
+ query FindTranslation($filter: TranslationFilterInput) {
1234
+ translations(filter: $filter, limit: 50, offset: 0) {
1235
+ items {
1236
+ id
1237
+ value
1238
+ status
1239
+ tenantId
1240
+ }
1241
+ }
1242
+ }
1243
+ `;
1244
+ const response = await this.client.query(query, {
1245
+ filter: {
1246
+ keyId,
1247
+ languageCode
1248
+ }
1249
+ }, this.context);
1250
+ const globalTranslation = response.translations.items.find((item) => item.tenantId === null);
1251
+ if (!globalTranslation) {
1252
+ return null;
1253
+ }
1254
+ return {
1255
+ id: globalTranslation.id,
1256
+ value: globalTranslation.value,
1257
+ status: globalTranslation.status
1258
+ };
1259
+ }
1260
+ async createLanguageTranslation(keyId, languageCode, value) {
1261
+ const mutation = `
1262
+ mutation CreateTranslation($input: CreateTranslationInput!) {
1263
+ createTranslation(input: $input) {
1264
+ id
1265
+ status
1266
+ }
1267
+ }
1268
+ `;
1269
+ const response = await this.client.query(mutation, {
1270
+ input: {
1271
+ keyId,
1272
+ languageCode,
1273
+ value
1274
+ }
1275
+ }, this.context);
1276
+ return response.createTranslation;
1277
+ }
1278
+ async updateLanguageTranslation(id, value, status) {
1279
+ const mutation = `
1280
+ mutation UpdateTranslation($id: ID!, $input: UpdateTranslationInput!) {
1281
+ updateTranslation(id: $id, input: $input) {
1282
+ id
1283
+ status
1284
+ }
1285
+ }
1286
+ `;
1287
+ await this.client.query(mutation, {
1288
+ id,
1289
+ input: {
1290
+ value,
1291
+ status
1292
+ }
1293
+ }, this.context);
1294
+ }
1295
+ /**
1296
+ * Escape regex special characters in a string
1297
+ */
1298
+ escapeRegex(str) {
1299
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1300
+ }
1301
+ /**
1302
+ * Interpolate variables in translation string
1303
+ */
1304
+ interpolate(text, variables) {
1305
+ let result = text;
1306
+ for (const [key, value] of Object.entries(variables)) {
1307
+ const escapedKey = this.escapeRegex(key);
1308
+ const regex = new RegExp(`{{\\s*${escapedKey}\\s*}}`, "g");
1309
+ result = result.replace(regex, String(value));
1310
+ }
1311
+ return result;
1312
+ }
1313
+ /**
1314
+ * Format translation with pluralization
1315
+ */
1316
+ formatPlural(_language, count, translations) {
1317
+ if (count === 0 && translations.zero) {
1318
+ return translations.zero;
1319
+ }
1320
+ if (count === 1) {
1321
+ return translations.one;
1322
+ }
1323
+ return translations.other;
1324
+ }
1325
+ /**
1326
+ * Format date/time for locale
1327
+ */
1328
+ formatDateTime(date, language, options) {
1329
+ const dateObj = typeof date === "string" ? new Date(date) : date;
1330
+ return new Intl.DateTimeFormat(language, options).format(dateObj);
1331
+ }
1332
+ /**
1333
+ * Format number for locale
1334
+ */
1335
+ formatNumber(number, language, options) {
1336
+ return new Intl.NumberFormat(language, options).format(number);
1337
+ }
1338
+ /**
1339
+ * Format currency for locale
1340
+ */
1341
+ formatCurrency(amount, currency, language) {
1342
+ return new Intl.NumberFormat(language, {
1343
+ style: "currency",
1344
+ currency
1345
+ }).format(amount);
1346
+ }
1347
+ };
1348
+
1349
+ // src/payments/index.ts
1350
+ var PaymentsModule = class {
1351
+ static {
1352
+ __name(this, "PaymentsModule");
1353
+ }
1354
+ client;
1355
+ context;
1356
+ constructor(client, context) {
1357
+ this.client = client;
1358
+ this.context = context;
1359
+ }
1360
+ /**
1361
+ * Create payment
1362
+ */
1363
+ async createPayment(options) {
1364
+ if (typeof options.amount !== "number" || options.amount <= 0) {
1365
+ throw new ValidationError("Amount must be a positive number");
1366
+ }
1367
+ if (!options.currency) {
1368
+ throw new ValidationError("Currency is required");
1369
+ }
1370
+ if (!options.paymentMethod) {
1371
+ throw new ValidationError("Payment method is required");
1372
+ }
1373
+ if (!options.customerId) {
1374
+ throw new ValidationError("Customer ID is required");
1375
+ }
1376
+ logger.debug("[Payments] Creating payment", {
1377
+ amount: options.amount,
1378
+ currency: options.currency,
1379
+ customerId: options.customerId
1380
+ });
1381
+ const mutation = `
1382
+ mutation CreatePayment($input: CreatePaymentInput!) {
1383
+ createPayment(input: $input) {
1384
+ id
1385
+ amount
1386
+ currency
1387
+ status
1388
+ paymentMethod
1389
+ customerId
1390
+ description
1391
+ metadata
1392
+ workspaceId
1393
+ organizationId
1394
+ transactionId
1395
+ failureReason
1396
+ createdAt
1397
+ updatedAt
1398
+ }
1399
+ }
1400
+ `;
1401
+ const variables = {
1402
+ input: {
1403
+ amount: options.amount,
1404
+ currency: options.currency,
1405
+ paymentMethod: options.paymentMethod,
1406
+ customerId: options.customerId,
1407
+ description: options.description,
1408
+ metadata: options.metadata,
1409
+ workspaceId: options.workspaceId || this.context.workspaceId,
1410
+ organizationId: options.organizationId
1411
+ }
1412
+ };
1413
+ const response = await this.client.query(mutation, variables, this.context);
1414
+ logger.info("[Payments] Payment created", {
1415
+ paymentId: response.createPayment.id
1416
+ });
1417
+ return response.createPayment;
1418
+ }
1419
+ /**
1420
+ * Get payment by ID
1421
+ */
1422
+ async getPayment(paymentId) {
1423
+ logger.debug("[Payments] Getting payment", {
1424
+ paymentId
1425
+ });
1426
+ const query = `
1427
+ query GetPayment($paymentId: ID!) {
1428
+ getPayment(paymentId: $paymentId) {
1429
+ id
1430
+ amount
1431
+ currency
1432
+ status
1433
+ paymentMethod
1434
+ customerId
1435
+ description
1436
+ metadata
1437
+ workspaceId
1438
+ organizationId
1439
+ transactionId
1440
+ failureReason
1441
+ createdAt
1442
+ updatedAt
1443
+ }
1444
+ }
1445
+ `;
1446
+ const response = await this.client.query(query, {
1447
+ paymentId
1448
+ }, this.context);
1449
+ return response.getPayment;
1450
+ }
1451
+ /**
1452
+ * Get payments with filters
1453
+ */
1454
+ async getPayments(options) {
1455
+ logger.debug("[Payments] Getting payments", options);
1456
+ const query = `
1457
+ query GetPayments(
1458
+ $customerId: ID
1459
+ $status: PaymentStatus
1460
+ $workspaceId: ID
1461
+ $organizationId: ID
1462
+ $startDate: DateTime
1463
+ $endDate: DateTime
1464
+ $limit: Int
1465
+ $offset: Int
1466
+ ) {
1467
+ getPayments(
1468
+ customerId: $customerId
1469
+ status: $status
1470
+ workspaceId: $workspaceId
1471
+ organizationId: $organizationId
1472
+ startDate: $startDate
1473
+ endDate: $endDate
1474
+ limit: $limit
1475
+ offset: $offset
1476
+ ) {
1477
+ payments {
1478
+ id
1479
+ amount
1480
+ currency
1481
+ status
1482
+ paymentMethod
1483
+ customerId
1484
+ description
1485
+ transactionId
1486
+ createdAt
1487
+ updatedAt
1488
+ }
1489
+ total
1490
+ }
1491
+ }
1492
+ `;
1493
+ const variables = {
1494
+ customerId: options.customerId,
1495
+ status: options.status,
1496
+ workspaceId: options.workspaceId || this.context.workspaceId,
1497
+ organizationId: options.organizationId,
1498
+ startDate: options.startDate,
1499
+ endDate: options.endDate,
1500
+ limit: options.limit || 50,
1501
+ offset: options.offset || 0
1502
+ };
1503
+ const response = await this.client.query(query, variables, this.context);
1504
+ return response.getPayments;
1505
+ }
1506
+ /**
1507
+ * Refund payment
1508
+ */
1509
+ async refundPayment(paymentId, amount, reason) {
1510
+ logger.debug("[Payments] Refunding payment", {
1511
+ paymentId,
1512
+ amount
1513
+ });
1514
+ const mutation = `
1515
+ mutation RefundPayment($paymentId: ID!, $amount: Int, $reason: String) {
1516
+ refundPayment(paymentId: $paymentId, amount: $amount, reason: $reason) {
1517
+ id
1518
+ amount
1519
+ currency
1520
+ status
1521
+ paymentMethod
1522
+ customerId
1523
+ failureReason
1524
+ updatedAt
1525
+ }
1526
+ }
1527
+ `;
1528
+ const response = await this.client.query(mutation, {
1529
+ paymentId,
1530
+ amount,
1531
+ reason
1532
+ }, this.context);
1533
+ logger.info("[Payments] Payment refunded", {
1534
+ paymentId
1535
+ });
1536
+ return response.refundPayment;
1537
+ }
1538
+ /**
1539
+ * Verify payment
1540
+ */
1541
+ async verifyPayment(paymentId, verificationData) {
1542
+ logger.debug("[Payments] Verifying payment", {
1543
+ paymentId
1544
+ });
1545
+ const mutation = `
1546
+ mutation VerifyPayment($paymentId: ID!, $verificationData: JSON!) {
1547
+ verifyPayment(paymentId: $paymentId, verificationData: $verificationData) {
1548
+ verified
1549
+ status
1550
+ }
1551
+ }
1552
+ `;
1553
+ const response = await this.client.query(mutation, {
1554
+ paymentId,
1555
+ verificationData
1556
+ }, this.context);
1557
+ logger.info("[Payments] Payment verified", {
1558
+ paymentId,
1559
+ verified: response.verifyPayment.verified
1560
+ });
1561
+ return response.verifyPayment;
1562
+ }
1563
+ /**
1564
+ * Create subscription
1565
+ */
1566
+ async createSubscription(options) {
1567
+ if (!options.customerId) {
1568
+ throw new ValidationError("Customer ID is required");
1569
+ }
1570
+ if (!options.planId) {
1571
+ throw new ValidationError("Plan ID is required");
1572
+ }
1573
+ if (!options.paymentMethod) {
1574
+ throw new ValidationError("Payment method is required");
1575
+ }
1576
+ logger.debug("[Payments] Creating subscription", {
1577
+ customerId: options.customerId,
1578
+ planId: options.planId
1579
+ });
1580
+ const mutation = `
1581
+ mutation CreateSubscription($input: CreateSubscriptionInput!) {
1582
+ createSubscription(input: $input) {
1583
+ id
1584
+ customerId
1585
+ planId
1586
+ status
1587
+ currentPeriodStart
1588
+ currentPeriodEnd
1589
+ trialEnd
1590
+ cancelledAt
1591
+ endedAt
1592
+ metadata
1593
+ workspaceId
1594
+ organizationId
1595
+ createdAt
1596
+ updatedAt
1597
+ }
1598
+ }
1599
+ `;
1600
+ const variables = {
1601
+ input: {
1602
+ customerId: options.customerId,
1603
+ planId: options.planId,
1604
+ paymentMethod: options.paymentMethod,
1605
+ trialDays: options.trialDays,
1606
+ metadata: options.metadata,
1607
+ workspaceId: options.workspaceId || this.context.workspaceId,
1608
+ organizationId: options.organizationId
1609
+ }
1610
+ };
1611
+ const response = await this.client.query(mutation, variables, this.context);
1612
+ logger.info("[Payments] Subscription created", {
1613
+ subscriptionId: response.createSubscription.id
1614
+ });
1615
+ return response.createSubscription;
1616
+ }
1617
+ /**
1618
+ * Get subscription
1619
+ */
1620
+ async getSubscription(subscriptionId) {
1621
+ logger.debug("[Payments] Getting subscription", {
1622
+ subscriptionId
1623
+ });
1624
+ const query = `
1625
+ query GetSubscription($subscriptionId: ID!) {
1626
+ getSubscription(subscriptionId: $subscriptionId) {
1627
+ id
1628
+ customerId
1629
+ planId
1630
+ status
1631
+ currentPeriodStart
1632
+ currentPeriodEnd
1633
+ trialEnd
1634
+ cancelledAt
1635
+ endedAt
1636
+ metadata
1637
+ workspaceId
1638
+ organizationId
1639
+ createdAt
1640
+ updatedAt
1641
+ }
1642
+ }
1643
+ `;
1644
+ const response = await this.client.query(query, {
1645
+ subscriptionId
1646
+ }, this.context);
1647
+ return response.getSubscription;
1648
+ }
1649
+ /**
1650
+ * Cancel subscription
1651
+ */
1652
+ async cancelSubscription(subscriptionId, cancelAtPeriodEnd = false) {
1653
+ logger.debug("[Payments] Cancelling subscription", {
1654
+ subscriptionId,
1655
+ cancelAtPeriodEnd
1656
+ });
1657
+ const mutation = `
1658
+ mutation CancelSubscription($subscriptionId: ID!, $cancelAtPeriodEnd: Boolean!) {
1659
+ cancelSubscription(subscriptionId: $subscriptionId, cancelAtPeriodEnd: $cancelAtPeriodEnd) {
1660
+ id
1661
+ status
1662
+ cancelledAt
1663
+ endedAt
1664
+ updatedAt
1665
+ }
1666
+ }
1667
+ `;
1668
+ const response = await this.client.query(mutation, {
1669
+ subscriptionId,
1670
+ cancelAtPeriodEnd
1671
+ }, this.context);
1672
+ logger.info("[Payments] Subscription cancelled", {
1673
+ subscriptionId
1674
+ });
1675
+ return response.cancelSubscription;
1676
+ }
1677
+ /**
1678
+ * Get customer subscriptions
1679
+ */
1680
+ async getCustomerSubscriptions(customerId) {
1681
+ logger.debug("[Payments] Getting customer subscriptions", {
1682
+ customerId
1683
+ });
1684
+ const query = `
1685
+ query GetCustomerSubscriptions($customerId: ID!) {
1686
+ getCustomerSubscriptions(customerId: $customerId) {
1687
+ id
1688
+ customerId
1689
+ planId
1690
+ status
1691
+ currentPeriodStart
1692
+ currentPeriodEnd
1693
+ trialEnd
1694
+ cancelledAt
1695
+ createdAt
1696
+ }
1697
+ }
1698
+ `;
1699
+ const response = await this.client.query(query, {
1700
+ customerId
1701
+ }, this.context);
1702
+ return response.getCustomerSubscriptions;
1703
+ }
1704
+ /**
1705
+ * Get plans
1706
+ */
1707
+ async getPlans(activeOnly = true) {
1708
+ logger.debug("[Payments] Getting plans", {
1709
+ activeOnly
1710
+ });
1711
+ const query = `
1712
+ query GetPlans($activeOnly: Boolean!) {
1713
+ getPlans(activeOnly: $activeOnly) {
1714
+ id
1715
+ name
1716
+ description
1717
+ amount
1718
+ currency
1719
+ interval
1720
+ intervalCount
1721
+ features
1722
+ metadata
1723
+ active
1724
+ createdAt
1725
+ }
1726
+ }
1727
+ `;
1728
+ const response = await this.client.query(query, {
1729
+ activeOnly
1730
+ }, this.context);
1731
+ return response.getPlans;
1732
+ }
1733
+ /**
1734
+ * Create payment intent
1735
+ */
1736
+ async createPaymentIntent(options) {
1737
+ logger.debug("[Payments] Creating payment intent", {
1738
+ amount: options.amount,
1739
+ currency: options.currency
1740
+ });
1741
+ const mutation = `
1742
+ mutation CreatePaymentIntent($input: CreatePaymentIntentInput!) {
1743
+ createPaymentIntent(input: $input) {
1744
+ clientSecret
1745
+ paymentIntentId
1746
+ }
1747
+ }
1748
+ `;
1749
+ const response = await this.client.query(mutation, {
1750
+ input: options
1751
+ }, this.context);
1752
+ logger.info("[Payments] Payment intent created", {
1753
+ paymentIntentId: response.createPaymentIntent.paymentIntentId
1754
+ });
1755
+ return response.createPaymentIntent;
1756
+ }
1757
+ /**
1758
+ * Get payment statistics
1759
+ */
1760
+ async getPaymentStats(options) {
1761
+ logger.debug("[Payments] Getting payment statistics", options);
1762
+ const query = `
1763
+ query GetPaymentStats($startDate: DateTime, $endDate: DateTime, $workspaceId: ID) {
1764
+ getPaymentStats(startDate: $startDate, endDate: $endDate, workspaceId: $workspaceId) {
1765
+ totalRevenue
1766
+ totalPayments
1767
+ successfulPayments
1768
+ failedPayments
1769
+ refundedAmount
1770
+ averagePaymentAmount
1771
+ }
1772
+ }
1773
+ `;
1774
+ const response = await this.client.query(query, {
1775
+ startDate: options?.startDate,
1776
+ endDate: options?.endDate,
1777
+ workspaceId: options?.workspaceId || this.context.workspaceId
1778
+ }, this.context);
1779
+ return response.getPaymentStats;
1780
+ }
1781
+ };
1782
+
1783
+ // src/bootstrap/index.ts
1784
+ var BootstrapModule = class {
1785
+ static {
1786
+ __name(this, "BootstrapModule");
1787
+ }
1788
+ config;
1789
+ startTime;
1790
+ healthCheckInterval;
1791
+ constructor(config) {
1792
+ this.config = config;
1793
+ this.startTime = /* @__PURE__ */ new Date();
1794
+ }
1795
+ /**
1796
+ * Bootstrap the application
1797
+ */
1798
+ async bootstrap() {
1799
+ logger.info("[Bootstrap] Starting application bootstrap", {
1800
+ serviceName: this.config.serviceName,
1801
+ environment: this.config.environment || "development"
1802
+ });
1803
+ try {
1804
+ await this.validateConfiguration();
1805
+ const databaseConnected = await this.connectDatabase();
1806
+ const loadedModules = await this.loadModules();
1807
+ if (this.config.healthCheck) {
1808
+ await this.setupHealthChecks();
1809
+ }
1810
+ this.setupSignalHandlers();
1811
+ const result = {
1812
+ success: true,
1813
+ serviceName: this.config.serviceName || "burdenoff-service",
1814
+ serviceVersion: this.config.serviceVersion || "1.0.0",
1815
+ environment: this.config.environment || "development",
1816
+ startedAt: this.startTime.toISOString(),
1817
+ modules: loadedModules,
1818
+ databaseConnected,
1819
+ healthCheckEnabled: this.config.healthCheck || false
1820
+ };
1821
+ logger.info("[Bootstrap] Application bootstrapped successfully", result);
1822
+ return result;
1823
+ } catch (error) {
1824
+ logger.error("[Bootstrap] Failed to bootstrap application", {
1825
+ error
1826
+ });
1827
+ throw error;
1828
+ }
1829
+ }
1830
+ /**
1831
+ * Validate configuration
1832
+ */
1833
+ async validateConfiguration() {
1834
+ logger.debug("[Bootstrap] Validating configuration");
1835
+ if (!this.config.workspacesApiUrl) {
1836
+ throw new Error("Workspaces API URL is required");
1837
+ }
1838
+ if (this.config.database?.url && !DatabaseModule.validateDatabaseUrl(this.config.database.url)) {
1839
+ throw new Error("Invalid database URL");
1840
+ }
1841
+ logger.debug("[Bootstrap] Configuration validated");
1842
+ }
1843
+ /**
1844
+ * Connect to database
1845
+ */
1846
+ async connectDatabase() {
1847
+ if (!this.config.database) {
1848
+ logger.debug("[Bootstrap] No database configuration provided, skipping");
1849
+ return false;
1850
+ }
1851
+ logger.info("[Bootstrap] Connecting to database");
1852
+ try {
1853
+ const sanitizedUrl = DatabaseModule.sanitizeDatabaseUrl(this.config.database.url);
1854
+ logger.info("[Bootstrap] Database connection configured", {
1855
+ url: sanitizedUrl
1856
+ });
1857
+ return true;
1858
+ } catch (error) {
1859
+ logger.error("[Bootstrap] Failed to connect to database", {
1860
+ error
1861
+ });
1862
+ return false;
1863
+ }
1864
+ }
1865
+ /**
1866
+ * Load modules
1867
+ */
1868
+ async loadModules() {
1869
+ const modules = this.config.modules || [];
1870
+ if (modules.length === 0) {
1871
+ logger.debug("[Bootstrap] No modules to load");
1872
+ return [];
1873
+ }
1874
+ logger.info("[Bootstrap] Loading modules", {
1875
+ modules
1876
+ });
1877
+ const loadedModules = [];
1878
+ for (const moduleName of modules) {
1879
+ try {
1880
+ logger.debug(`[Bootstrap] Loading module: ${moduleName}`);
1881
+ loadedModules.push(moduleName);
1882
+ } catch (error) {
1883
+ logger.error(`[Bootstrap] Failed to load module: ${moduleName}`, {
1884
+ error
1885
+ });
1886
+ }
1887
+ }
1888
+ logger.info("[Bootstrap] Modules loaded", {
1889
+ loaded: loadedModules
1890
+ });
1891
+ return loadedModules;
1892
+ }
1893
+ /**
1894
+ * Setup health checks
1895
+ */
1896
+ async setupHealthChecks() {
1897
+ logger.info("[Bootstrap] Setting up health checks");
1898
+ const interval = this.config.healthCheckInterval || 3e4;
1899
+ this.healthCheckInterval = setInterval(() => {
1900
+ void (async () => {
1901
+ const health = await this.performHealthCheck();
1902
+ if (!health.healthy) {
1903
+ logger.warn("[Bootstrap] Health check failed", health);
1904
+ } else {
1905
+ logger.debug("[Bootstrap] Health check passed", health);
1906
+ }
1907
+ })();
1908
+ }, interval);
1909
+ logger.info("[Bootstrap] Health checks configured", {
1910
+ interval
1911
+ });
1912
+ }
1913
+ /**
1914
+ * Perform health check
1915
+ */
1916
+ async performHealthCheck() {
1917
+ const checks = {};
1918
+ const memUsage = process.memoryUsage();
1919
+ checks.memory = {
1920
+ used: memUsage.heapUsed,
1921
+ total: memUsage.heapTotal,
1922
+ percentage: memUsage.heapUsed / memUsage.heapTotal * 100
1923
+ };
1924
+ checks.uptime = Math.floor((Date.now() - this.startTime.getTime()) / 1e3);
1925
+ const healthy = checks.memory.percentage < 90 && // Less than 90% memory usage
1926
+ checks.uptime > 0;
1927
+ return {
1928
+ healthy,
1929
+ checks,
1930
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1931
+ };
1932
+ }
1933
+ /**
1934
+ * Setup signal handlers for graceful shutdown
1935
+ */
1936
+ setupSignalHandlers() {
1937
+ logger.debug("[Bootstrap] Setting up signal handlers");
1938
+ const gracefulShutdown = /* @__PURE__ */ __name(async (signal) => {
1939
+ logger.info(`[Bootstrap] Received ${signal}, shutting down gracefully`);
1940
+ if (this.healthCheckInterval) {
1941
+ clearInterval(this.healthCheckInterval);
1942
+ }
1943
+ await this.cleanup();
1944
+ process.exit(0);
1945
+ }, "gracefulShutdown");
1946
+ process.on("SIGTERM", () => {
1947
+ void gracefulShutdown("SIGTERM");
1948
+ });
1949
+ process.on("SIGINT", () => {
1950
+ void gracefulShutdown("SIGINT");
1951
+ });
1952
+ process.on("unhandledRejection", (reason, promise) => {
1953
+ logger.error("[Bootstrap] Unhandled rejection", {
1954
+ reason,
1955
+ promise
1956
+ });
1957
+ });
1958
+ process.on("uncaughtException", (error) => {
1959
+ logger.error("[Bootstrap] Uncaught exception", {
1960
+ error
1961
+ });
1962
+ process.exit(1);
1963
+ });
1964
+ }
1965
+ /**
1966
+ * Cleanup on shutdown
1967
+ */
1968
+ async cleanup() {
1969
+ logger.info("[Bootstrap] Performing cleanup");
1970
+ ContextManager.clearContext();
1971
+ logger.info("[Bootstrap] Cleanup completed");
1972
+ }
1973
+ /**
1974
+ * Get application info
1975
+ */
1976
+ getInfo() {
1977
+ return {
1978
+ serviceName: this.config.serviceName || "burdenoff-service",
1979
+ serviceVersion: this.config.serviceVersion || "1.0.0",
1980
+ environment: this.config.environment || "development",
1981
+ uptime: Math.floor((Date.now() - this.startTime.getTime()) / 1e3),
1982
+ startedAt: this.startTime.toISOString()
1983
+ };
1984
+ }
1985
+ /**
1986
+ * Setup default context
1987
+ */
1988
+ setupDefaultContext(context) {
1989
+ logger.debug("[Bootstrap] Setting up default context", context);
1990
+ ContextManager.setContext(context);
1991
+ }
1992
+ /**
1993
+ * Create context middleware (for Elysia/HTTP frameworks)
1994
+ */
1995
+ createContextMiddleware() {
1996
+ return async (req, _res, next) => {
1997
+ const context = this.extractContextFromRequest(req);
1998
+ ContextManager.setContext(context);
1999
+ next();
2000
+ };
2001
+ }
2002
+ /**
2003
+ * Extract context from request
2004
+ */
2005
+ extractContextFromRequest(req) {
2006
+ const context = {};
2007
+ if (req.user) {
2008
+ context.actorId = req.user.user_id;
2009
+ context.workspaceId = req.user.workspace_id;
2010
+ context.tenantId = req.user.tenant_endpoint;
2011
+ }
2012
+ const getHeader = /* @__PURE__ */ __name((key) => {
2013
+ const value = req.headers[key.toLowerCase()];
2014
+ return Array.isArray(value) ? value[0] : value;
2015
+ }, "getHeader");
2016
+ const authHeader = getHeader("authorization");
2017
+ if (authHeader) {
2018
+ context.token = authHeader.replace("Bearer ", "");
2019
+ }
2020
+ const workspaceId = getHeader("x-workspace-id");
2021
+ if (workspaceId && !context.workspaceId) {
2022
+ context.workspaceId = workspaceId;
2023
+ }
2024
+ const productId = getHeader("x-product-id");
2025
+ if (productId) {
2026
+ context.productId = productId;
2027
+ }
2028
+ const projectId = getHeader("x-project-id");
2029
+ if (projectId) {
2030
+ context.projectId = projectId;
2031
+ }
2032
+ const appId = getHeader("x-app-id");
2033
+ if (appId) {
2034
+ context.appId = appId;
2035
+ }
2036
+ return context;
2037
+ }
2038
+ /**
2039
+ * Load GraphQL schema
2040
+ */
2041
+ async loadSchema(schemaPath) {
2042
+ logger.info("[Bootstrap] Loading GraphQL schema", {
2043
+ schemaPath
2044
+ });
2045
+ try {
2046
+ logger.info("[Bootstrap] Schema loaded successfully");
2047
+ return true;
2048
+ } catch (error) {
2049
+ logger.error("[Bootstrap] Failed to load schema", {
2050
+ error
2051
+ });
2052
+ return false;
2053
+ }
2054
+ }
2055
+ /**
2056
+ * Register shutdown hook
2057
+ */
2058
+ onShutdown(callback) {
2059
+ const originalHandler = process.listeners("SIGTERM")[0];
2060
+ process.removeAllListeners("SIGTERM");
2061
+ process.on("SIGTERM", () => {
2062
+ void (async () => {
2063
+ await callback();
2064
+ if (typeof originalHandler === "function") {
2065
+ originalHandler();
2066
+ }
2067
+ })();
2068
+ });
2069
+ }
2070
+ /**
2071
+ * Check if application is ready
2072
+ */
2073
+ async isReady() {
2074
+ const health = await this.performHealthCheck();
2075
+ return health.healthy;
2076
+ }
2077
+ /**
2078
+ * Get metrics
2079
+ */
2080
+ getMetrics() {
2081
+ return {
2082
+ memory: process.memoryUsage(),
2083
+ uptime: Math.floor((Date.now() - this.startTime.getTime()) / 1e3),
2084
+ cpu: process.cpuUsage()
2085
+ };
2086
+ }
2087
+ };
2088
+ function createBootstrap(config) {
2089
+ return new BootstrapModule(config);
2090
+ }
2091
+ __name(createBootstrap, "createBootstrap");
2092
+
2093
+ // src/client/tenant-backend.ts
2094
+ var TenantBackendClient = class {
2095
+ static {
2096
+ __name(this, "TenantBackendClient");
2097
+ }
2098
+ graphqlClient;
2099
+ config;
2100
+ /** Notifications module for sending notifications via tenant backend */
2101
+ notifications;
2102
+ constructor(config) {
2103
+ this.config = config;
2104
+ const sdkConfig = {
2105
+ workspacesApiUrl: config.workspacesBackendUrl || "http://localhost:4000/graphql",
2106
+ tenantApiUrl: config.tenantBackendUrl
2107
+ };
2108
+ this.graphqlClient = new BurdenoffGraphQLClient(sdkConfig, {});
2109
+ this.notifications = new TenantNotificationsModule(this.graphqlClient, {});
2110
+ logger.info("[TenantBackend] Client initialized using be-sdk", {
2111
+ tenantUrl: config.tenantBackendUrl,
2112
+ workspacesUrl: config.workspacesBackendUrl,
2113
+ hasApiKey: !!config.apiKey
2114
+ });
2115
+ }
2116
+ /**
2117
+ * Update authentication token
2118
+ *
2119
+ * @param token - JWT token for authentication
2120
+ */
2121
+ setAuthToken(token) {
2122
+ this.graphqlClient.updateContext({
2123
+ token
2124
+ });
2125
+ logger.debug("[TenantBackend] Authentication token updated");
2126
+ }
2127
+ /**
2128
+ * Execute raw GraphQL query against tenant backend
2129
+ *
2130
+ * @param query - GraphQL query string
2131
+ * @param variables - Query variables
2132
+ * @returns Query result
2133
+ *
2134
+ * @example
2135
+ * ```typescript
2136
+ * const result = await client.query(`
2137
+ * query GetTemplate($slug: String!) {
2138
+ * notificationTemplate(slug: $slug) {
2139
+ * id
2140
+ * slug
2141
+ * subject
2142
+ * }
2143
+ * }
2144
+ * `, { slug: 'user-welcome' });
2145
+ * ```
2146
+ */
2147
+ async query(query, variables) {
2148
+ return this.graphqlClient.tenantQuery(query, variables);
2149
+ }
2150
+ /**
2151
+ * Health check
2152
+ *
2153
+ * @returns True if tenant backend is reachable, false otherwise
2154
+ */
2155
+ async healthCheck() {
2156
+ try {
2157
+ const query = `
2158
+ query HealthCheck {
2159
+ __typename
2160
+ }
2161
+ `;
2162
+ await this.graphqlClient.tenantQuery(query);
2163
+ return true;
2164
+ } catch (error) {
2165
+ logger.error("[TenantBackend] Health check failed", {
2166
+ error: error instanceof Error ? error.message : "Unknown error"
2167
+ });
2168
+ return false;
2169
+ }
2170
+ }
2171
+ /**
2172
+ * Get GraphQL client for advanced usage
2173
+ *
2174
+ * @returns Underlying BurdenoffGraphQLClient
2175
+ */
2176
+ getClient() {
2177
+ return this.graphqlClient;
2178
+ }
2179
+ /**
2180
+ * Get client configuration
2181
+ *
2182
+ * @returns Client configuration
2183
+ */
2184
+ getConfig() {
2185
+ return {
2186
+ ...this.config
2187
+ };
2188
+ }
2189
+ };
2190
+ function createTenantBackendClient(config) {
2191
+ return new TenantBackendClient(config);
2192
+ }
2193
+ __name(createTenantBackendClient, "createTenantBackendClient");
2194
+
2195
+ // src/index.ts
2196
+ var BurdenoffSDK = class {
2197
+ static {
2198
+ __name(this, "BurdenoffSDK");
2199
+ }
2200
+ client;
2201
+ defaultContext;
2202
+ // NATS publisher state
2203
+ natsPublisher = null;
2204
+ natsInitPromise = null;
2205
+ natsConfig = null;
2206
+ // Initialization state
2207
+ initializationPromise = null;
2208
+ isShuttingDown = false;
2209
+ /** Authentication module */
2210
+ auth;
2211
+ /** Notifications module (workspaces-backend) */
2212
+ notifications;
2213
+ /** Tenant Notifications module (tenant-backend - RECOMMENDED) */
2214
+ tenantNotifications;
2215
+ /** RBAC module */
2216
+ rbac;
2217
+ /** Activity tracking module */
2218
+ activity;
2219
+ /** Usage & Quota module */
2220
+ usage;
2221
+ /** Unified Tracker module (MOST IMPORTANT - use this for most operations) */
2222
+ tracker;
2223
+ /** Database helpers module */
2224
+ database;
2225
+ /** Events/Queue module */
2226
+ events;
2227
+ /** Graph integration module */
2228
+ graph;
2229
+ /** Search module */
2230
+ search;
2231
+ /** Translation module */
2232
+ translation;
2233
+ /** Payments module */
2234
+ payments;
2235
+ /** Temporal workflow orchestration module (lazy-loaded) */
2236
+ _temporal = null;
2237
+ _temporalPromise = null;
2238
+ _temporalConfig = null;
2239
+ /**
2240
+ * Get Temporal workflow orchestration module (lazy-loaded)
2241
+ * Only loads @temporalio/client when this method is called
2242
+ *
2243
+ * @returns Promise resolving to TemporalModule
2244
+ * @example
2245
+ * ```typescript
2246
+ * const temporal = await sdk.getTemporalModule();
2247
+ * await temporal.startWorkflow('myWorkflow', { ... });
2248
+ * ```
2249
+ */
2250
+ async getTemporalModule() {
2251
+ if (this._temporal) {
2252
+ return this._temporal;
2253
+ }
2254
+ if (!this._temporalPromise) {
2255
+ this._temporalPromise = this.loadTemporalModule();
2256
+ }
2257
+ return this._temporalPromise;
2258
+ }
2259
+ /**
2260
+ * Load temporal module dynamically
2261
+ * @private
2262
+ */
2263
+ async loadTemporalModule() {
2264
+ const { TemporalModule: TM } = await import('./temporal/index.js');
2265
+ this._temporal = this._temporalConfig?.moduleType ? new TM({
2266
+ moduleType: this._temporalConfig.moduleType,
2267
+ address: this._temporalConfig.address,
2268
+ namespace: this._temporalConfig.namespace,
2269
+ taskQueue: this._temporalConfig.taskQueue
2270
+ }) : TM.fromEnv();
2271
+ return this._temporal;
2272
+ }
2273
+ /** Logger instance */
2274
+ logger;
2275
+ /** Context manager */
2276
+ context;
2277
+ /**
2278
+ * Create SDK instance
2279
+ */
2280
+ constructor(config, defaultContext = {}) {
2281
+ this.client = new BurdenoffGraphQLClient(config, defaultContext);
2282
+ this.defaultContext = defaultContext;
2283
+ this.logger = logger;
2284
+ if (config.logger) {
2285
+ this.logger.setLevel(config.logger.level);
2286
+ this.logger.setConsoleEnabled(config.logger.console);
2287
+ if (config.logger.transport) {
2288
+ this.logger.addTransport(config.logger.transport);
2289
+ }
2290
+ }
2291
+ this.context = ContextManager;
2292
+ if (Object.keys(defaultContext).length > 0) {
2293
+ ContextManager.setContext(defaultContext);
2294
+ }
2295
+ this.auth = new AuthModule(this.client, defaultContext);
2296
+ this.notifications = new NotificationsModule(this.client, defaultContext);
2297
+ this.tenantNotifications = new TenantNotificationsModule(this.client, defaultContext);
2298
+ this.rbac = new RBACModule(this.client, defaultContext);
2299
+ this.activity = new ActivityModule(this.client, defaultContext);
2300
+ this.usage = new UsageModule(this.client, defaultContext);
2301
+ this.tracker = new TrackerModule(this.client, defaultContext);
2302
+ this.database = DatabaseModule;
2303
+ this.events = new EventsModule(this.client, defaultContext);
2304
+ this.graph = new GraphModule(this.client, defaultContext);
2305
+ this.search = new SearchModule(this.client, defaultContext);
2306
+ this.translation = new TranslationModule(this.client, defaultContext);
2307
+ this.payments = new PaymentsModule(this.client, defaultContext);
2308
+ if (config.temporalModuleType) {
2309
+ this._temporalConfig = {
2310
+ moduleType: config.temporalModuleType,
2311
+ address: config.temporalAddress,
2312
+ namespace: config.temporalNamespace,
2313
+ taskQueue: config.temporalTaskQueue
2314
+ };
2315
+ }
2316
+ if (config.nats) {
2317
+ this.natsConfig = {
2318
+ autoConnect: true,
2319
+ maxReconnectAttempts: -1,
2320
+ reconnectTimeWait: 2e3,
2321
+ ...config.nats
2322
+ };
2323
+ }
2324
+ logger.info("[SDK] Burdenoff SDK initialized", {
2325
+ workspacesApiUrl: config.workspacesApiUrl,
2326
+ tenantApiUrl: config.tenantApiUrl,
2327
+ hasDefaultContext: Object.keys(defaultContext).length > 0,
2328
+ hasNatsConfig: !!config.nats,
2329
+ hasTemporalConfig: !!config.temporalModuleType
2330
+ });
2331
+ this.scheduleBackgroundInit();
2332
+ }
2333
+ /**
2334
+ * Schedule background initialization outside constructor
2335
+ * Uses queueMicrotask to defer async work while maintaining initialization order
2336
+ * @private
2337
+ */
2338
+ scheduleBackgroundInit() {
2339
+ queueMicrotask(() => {
2340
+ this.initializationPromise = this.initializeAsync();
2341
+ });
2342
+ }
2343
+ /**
2344
+ * Update SDK context
2345
+ */
2346
+ setContext(context) {
2347
+ this.defaultContext = {
2348
+ ...this.defaultContext,
2349
+ ...context
2350
+ };
2351
+ this.client.updateContext(context);
2352
+ ContextManager.setContext(this.defaultContext);
2353
+ }
2354
+ /**
2355
+ * Get current context
2356
+ */
2357
+ getContext() {
2358
+ return ContextManager.getContext();
2359
+ }
2360
+ /**
2361
+ * Run function with specific context
2362
+ */
2363
+ async withContext(context, fn) {
2364
+ return ContextManager.withContext(context, fn);
2365
+ }
2366
+ /**
2367
+ * Background initialization for NATS and other async resources
2368
+ * @private
2369
+ */
2370
+ async initializeAsync() {
2371
+ const promises = [];
2372
+ if (this.natsConfig?.autoConnect) {
2373
+ promises.push(this.initializeNats().catch((error) => {
2374
+ logger.warn("[SDK] Failed to auto-connect to NATS", {
2375
+ error
2376
+ });
2377
+ }));
2378
+ }
2379
+ await Promise.allSettled(promises);
2380
+ }
2381
+ /**
2382
+ * Initialize NATS publisher
2383
+ * @private
2384
+ */
2385
+ async initializeNats() {
2386
+ if (!this.natsConfig || this.natsPublisher) return;
2387
+ const natsUrl = this.natsConfig.url || this.natsConfig.servers && this.natsConfig.servers[0] || "nats://localhost:4222";
2388
+ const publisherConfig = {
2389
+ type: "nats",
2390
+ url: natsUrl,
2391
+ user: this.natsConfig.user,
2392
+ password: this.natsConfig.password,
2393
+ token: this.natsConfig.token,
2394
+ name: this.natsConfig.name || "burdenoff-sdk-publisher",
2395
+ maxReconnectAttempts: this.natsConfig.maxReconnectAttempts ?? -1,
2396
+ reconnectTimeWait: this.natsConfig.reconnectTimeWait ?? 2e3
2397
+ };
2398
+ this.natsPublisher = EventQueueFactory.createPublisher(publisherConfig);
2399
+ await this.natsPublisher.connect();
2400
+ logger.info("[SDK] NATS publisher initialized", {
2401
+ url: natsUrl,
2402
+ name: this.natsConfig.name
2403
+ });
2404
+ }
2405
+ /**
2406
+ * Get NATS publisher instance (lazy initialization)
2407
+ *
2408
+ * @example
2409
+ * ```typescript
2410
+ * const publisher = await sdk.getNatsPublisher();
2411
+ * await publisher.publish({
2412
+ * subject: 'events.user.created',
2413
+ * data: { userId: 'user-123' }
2414
+ * });
2415
+ * ```
2416
+ */
2417
+ async getNatsPublisher() {
2418
+ if (this.natsPublisher) return this.natsPublisher;
2419
+ if (!this.natsConfig) {
2420
+ throw new Error("[SDK] NATS not configured - provide nats config in SDKConfig");
2421
+ }
2422
+ if (!this.natsInitPromise) {
2423
+ this.natsInitPromise = this.initializeNats();
2424
+ }
2425
+ await this.natsInitPromise;
2426
+ if (!this.natsPublisher) {
2427
+ throw new Error("[SDK] NATS initialization failed");
2428
+ }
2429
+ return this.natsPublisher;
2430
+ }
2431
+ /**
2432
+ * Wait for SDK initialization to complete
2433
+ *
2434
+ * @example
2435
+ * ```typescript
2436
+ * await sdk.waitForReady();
2437
+ * ```
2438
+ */
2439
+ async waitForReady() {
2440
+ if (this.initializationPromise) {
2441
+ await this.initializationPromise;
2442
+ }
2443
+ }
2444
+ /**
2445
+ * Check NATS health status
2446
+ *
2447
+ * @example
2448
+ * ```typescript
2449
+ * const health = await sdk.isNatsHealthy();
2450
+ * if (health.status === 'healthy') {
2451
+ * console.log('NATS is connected');
2452
+ * }
2453
+ * ```
2454
+ */
2455
+ async isNatsHealthy() {
2456
+ if (!this.natsConfig) {
2457
+ return {
2458
+ status: "not_configured",
2459
+ connected: false
2460
+ };
2461
+ }
2462
+ if (!this.natsPublisher) {
2463
+ return {
2464
+ status: "unhealthy",
2465
+ connected: false,
2466
+ url: this.natsConfig.url,
2467
+ details: {
2468
+ reason: "Not initialized"
2469
+ }
2470
+ };
2471
+ }
2472
+ try {
2473
+ const healthCheck = await this.natsPublisher.healthCheck();
2474
+ return {
2475
+ status: healthCheck.status,
2476
+ connected: this.natsPublisher.isConnected(),
2477
+ url: this.natsConfig.url,
2478
+ details: healthCheck.details
2479
+ };
2480
+ } catch (error) {
2481
+ return {
2482
+ status: "unhealthy",
2483
+ connected: false,
2484
+ url: this.natsConfig.url,
2485
+ details: {
2486
+ error: error instanceof Error ? error.message : String(error)
2487
+ }
2488
+ };
2489
+ }
2490
+ }
2491
+ /**
2492
+ * Check Temporal health status
2493
+ *
2494
+ * @example
2495
+ * ```typescript
2496
+ * const health = await sdk.isTemporalHealthy();
2497
+ * if (health.status === 'healthy') {
2498
+ * console.log('Temporal is connected');
2499
+ * }
2500
+ * ```
2501
+ */
2502
+ async isTemporalHealthy() {
2503
+ if (!this._temporal) {
2504
+ return {
2505
+ status: "not_configured",
2506
+ connected: false
2507
+ };
2508
+ }
2509
+ const config = this._temporal.getConfig();
2510
+ if (!config.address) {
2511
+ return {
2512
+ status: "not_configured",
2513
+ connected: false
2514
+ };
2515
+ }
2516
+ try {
2517
+ const client = this._temporal.getClient();
2518
+ const connected = client.isClientConnected();
2519
+ return {
2520
+ status: connected ? "healthy" : "unhealthy",
2521
+ connected,
2522
+ address: config.address,
2523
+ namespace: config.namespace,
2524
+ details: {
2525
+ taskQueue: config.taskQueue
2526
+ }
2527
+ };
2528
+ } catch (error) {
2529
+ return {
2530
+ status: "unhealthy",
2531
+ connected: false,
2532
+ address: config.address,
2533
+ namespace: config.namespace,
2534
+ details: {
2535
+ error: error instanceof Error ? error.message : String(error)
2536
+ }
2537
+ };
2538
+ }
2539
+ }
2540
+ /**
2541
+ * Get overall SDK health status
2542
+ *
2543
+ * @example
2544
+ * ```typescript
2545
+ * const health = await sdk.getHealthStatus();
2546
+ * console.log('NATS:', health.nats.status);
2547
+ * console.log('Temporal:', health.temporal.status);
2548
+ * ```
2549
+ */
2550
+ async getHealthStatus() {
2551
+ const [nats, temporal] = await Promise.all([
2552
+ this.isNatsHealthy(),
2553
+ this.isTemporalHealthy()
2554
+ ]);
2555
+ return {
2556
+ nats,
2557
+ temporal
2558
+ };
2559
+ }
2560
+ /**
2561
+ * Graceful shutdown - disconnect all resources
2562
+ *
2563
+ * @example
2564
+ * ```typescript
2565
+ * // On application shutdown
2566
+ * await sdk.shutdown({ timeout: 5000, force: true });
2567
+ * ```
2568
+ */
2569
+ async shutdown(options = {}) {
2570
+ if (this.isShuttingDown) {
2571
+ logger.warn("[SDK] Shutdown already in progress");
2572
+ return;
2573
+ }
2574
+ this.isShuttingDown = true;
2575
+ const timeout = options.timeout ?? 5e3;
2576
+ const force = options.force ?? true;
2577
+ logger.info("[SDK] Starting graceful shutdown", {
2578
+ timeout,
2579
+ force
2580
+ });
2581
+ const shutdownPromises = [];
2582
+ if (this.natsPublisher) {
2583
+ shutdownPromises.push(this.natsPublisher.disconnect().catch((error) => {
2584
+ logger.error("[SDK] Error disconnecting NATS", {
2585
+ error
2586
+ });
2587
+ }));
2588
+ }
2589
+ if (this._temporal) {
2590
+ shutdownPromises.push(this._temporal.disconnect().catch((error) => {
2591
+ logger.error("[SDK] Error disconnecting Temporal", {
2592
+ error
2593
+ });
2594
+ }));
2595
+ }
2596
+ try {
2597
+ await Promise.race([
2598
+ Promise.allSettled(shutdownPromises),
2599
+ new Promise((_, reject) => setTimeout(() => reject(new Error("[SDK] Shutdown timeout exceeded")), timeout))
2600
+ ]);
2601
+ logger.info("[SDK] Shutdown completed successfully");
2602
+ } catch (error) {
2603
+ if (!force) {
2604
+ throw error;
2605
+ }
2606
+ logger.warn("[SDK] Shutdown timeout exceeded, forcing shutdown", {
2607
+ error
2608
+ });
2609
+ }
2610
+ }
2611
+ /**
2612
+ * Create bootstrap instance
2613
+ */
2614
+ static createBootstrap(config) {
2615
+ return createBootstrap(config);
2616
+ }
2617
+ };
2618
+ var index_default = BurdenoffSDK;
2619
+ function createSDK(config, context) {
2620
+ return new BurdenoffSDK(config, context);
2621
+ }
2622
+ __name(createSDK, "createSDK");
2623
+
2624
+ export { BootstrapModule, BurdenoffGraphQLClient, BurdenoffSDK, ContextManager, PaymentsModule, SearchModule, TenantBackendClient, TranslationModule, createBootstrap, createSDK, createTenantBackendClient, index_default as default };
2625
+ //# sourceMappingURL=index.js.map
2626
+ //# sourceMappingURL=index.js.map