@coderule/clients 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -259,10 +259,26 @@ init_cjs_shims();
259
259
  var SyncHttpClient = class {
260
260
  /**
261
261
  * Initialize the Sync HTTP client
262
- * @param uri - URI/URL for connecting to the HTTP server (e.g., "http://localhost:8002")
263
- * @param timeout - Request timeout in milliseconds (default: 60000)
262
+ * @param config.baseUrl - URI/URL for connecting to the HTTP server (e.g., "http://localhost:8002")
263
+ * @param config.timeout - Request timeout in milliseconds (default: 60000)
264
+ * @param config.jwtProvider - Provider for obtaining JWT tokens
264
265
  */
265
- constructor(uri = "http://localhost:8002", timeout = 6e4) {
266
+ constructor({
267
+ baseUrl = "http://localhost:8002",
268
+ timeout = 6e4,
269
+ jwtProvider
270
+ }) {
271
+ if (!jwtProvider) {
272
+ throw new Error("SyncHttpClient requires a JWT provider");
273
+ }
274
+ this.timeout = timeout;
275
+ this.jwtProvider = jwtProvider;
276
+ this.configureBase(baseUrl);
277
+ }
278
+ updateBaseUrl(baseUrl) {
279
+ this.configureBase(baseUrl);
280
+ }
281
+ configureBase(uri) {
266
282
  let processedUri = uri;
267
283
  if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
268
284
  processedUri = `http://${uri}`;
@@ -273,7 +289,6 @@ var SyncHttpClient = class {
273
289
  } else {
274
290
  this.baseUrl = `${url.protocol}//${url.host}`;
275
291
  }
276
- this.timeout = timeout;
277
292
  if (this.baseUrl.endsWith("/")) {
278
293
  this.apiBase = `${this.baseUrl}sync/v1/`;
279
294
  } else {
@@ -283,14 +298,14 @@ var SyncHttpClient = class {
283
298
  /**
284
299
  * Check the status of a snapshot
285
300
  * @param snapshotHash - SHA256 hash of the snapshot
286
- * @param jwt - JWT token for authorization (required)
287
301
  * @returns Snapshot status information
288
302
  * @throws Error on HTTP errors or connection errors
289
303
  */
290
- async checkSnapshotStatus(snapshotHash, jwt) {
291
- if (!jwt) {
292
- throw new Error("JWT must be provided");
304
+ async checkSnapshotStatus(snapshotHash) {
305
+ if (!snapshotHash) {
306
+ throw new Error("Snapshot hash must be provided");
293
307
  }
308
+ const jwt = await this.jwtProvider.getJWT();
294
309
  const url = `${this.apiBase}snapshots`;
295
310
  try {
296
311
  const controller = new AbortController2();
@@ -328,14 +343,14 @@ var SyncHttpClient = class {
328
343
  * Create a new snapshot or get its status if it exists
329
344
  * @param snapshotHash - SHA256 hash of the snapshot
330
345
  * @param files - List of file information with 'file_path' and 'file_hash'
331
- * @param jwt - JWT token for authorization (required)
332
346
  * @returns Snapshot creation result or status
333
347
  * @throws Error on HTTP errors or connection errors
334
348
  */
335
- async createSnapshot(snapshotHash, files, jwt) {
336
- if (!jwt) {
337
- throw new Error("JWT must be provided");
349
+ async createSnapshot(snapshotHash, files) {
350
+ if (!snapshotHash) {
351
+ throw new Error("Snapshot hash must be provided");
338
352
  }
353
+ const jwt = await this.jwtProvider.getJWT();
339
354
  const url = `${this.apiBase}snapshots`;
340
355
  try {
341
356
  const controller = new AbortController2();
@@ -382,14 +397,11 @@ var SyncHttpClient = class {
382
397
  /**
383
398
  * Upload file content to the service
384
399
  * @param filesContent - Map of file_hash to object with 'path' and 'content'
385
- * @param jwt - JWT token for authorization (required)
386
400
  * @returns Upload result with counts
387
401
  * @throws Error on HTTP errors or connection errors
388
402
  */
389
- async uploadFileContent(filesContent, jwt) {
390
- if (!jwt) {
391
- throw new Error("JWT must be provided");
392
- }
403
+ async uploadFileContent(filesContent) {
404
+ const jwt = await this.jwtProvider.getJWT();
393
405
  const url = `${this.apiBase}files/content`;
394
406
  try {
395
407
  const controller = new AbortController2();
@@ -497,10 +509,28 @@ init_cjs_shims();
497
509
  var RetrievalHttpClient = class {
498
510
  /**
499
511
  * Initialize the Retrieval HTTP client
500
- * @param uri - URI/URL for connecting to the HTTP server (e.g., "http://localhost:8004")
501
- * @param timeout - Request timeout in milliseconds (default: 60000)
512
+ * @param config.baseUrl - URI/URL for connecting to the HTTP server (e.g., "http://localhost:8004")
513
+ * @param config.timeout - Request timeout in milliseconds (default: 60000)
514
+ * @param config.jwtProvider - Provider for obtaining JWT tokens
502
515
  */
503
- constructor(uri = "http://localhost:8004", timeout = 6e4) {
516
+ constructor({
517
+ baseUrl = "http://localhost:8004",
518
+ timeout = 6e4,
519
+ jwtProvider
520
+ }) {
521
+ if (!jwtProvider) {
522
+ throw new Error("RetrievalHttpClient requires a JWT provider");
523
+ }
524
+ this.timeout = timeout;
525
+ this.jwtProvider = jwtProvider;
526
+ this.configureBase(baseUrl);
527
+ console.debug(`Initialized HTTP client for ${this.baseUrl}`);
528
+ console.debug(`API base: ${this.apiBase}`);
529
+ }
530
+ updateBaseUrl(baseUrl) {
531
+ this.configureBase(baseUrl);
532
+ }
533
+ configureBase(uri) {
504
534
  let processedUri = uri;
505
535
  if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
506
536
  processedUri = `http://${uri}`;
@@ -511,14 +541,11 @@ var RetrievalHttpClient = class {
511
541
  } else {
512
542
  this.baseUrl = `${url.protocol}//${url.host}`;
513
543
  }
514
- this.timeout = timeout;
515
544
  if (this.baseUrl.endsWith("/")) {
516
545
  this.apiBase = `${this.baseUrl}api/retrieval/`;
517
546
  } else {
518
547
  this.apiBase = `${this.baseUrl}/api/retrieval/`;
519
548
  }
520
- console.debug(`Initialized HTTP client for ${this.baseUrl}`);
521
- console.debug(`API base: ${this.apiBase}`);
522
549
  }
523
550
  /**
524
551
  * Check the health status of the Retrieval service
@@ -567,25 +594,22 @@ var RetrievalHttpClient = class {
567
594
  * @param snapshotHash - SHA256 hash of the codebase snapshot
568
595
  * @param queryText - Natural language query for retrieval
569
596
  * @param budgetTokens - Maximum token budget for results (default: 3000)
570
- * @param jwt - JWT token for authorization (required)
571
597
  * @param options - Optional retrieval parameters
572
598
  * @returns Retrieval results with formatted output
573
599
  * @throws Error on query failures
574
600
  */
575
- async query(snapshotHash, queryText, budgetTokens = 3e3, jwt, options) {
601
+ async query(snapshotHash, queryText, budgetTokens = 3e3, options) {
576
602
  if (!snapshotHash) {
577
603
  throw new Error("Snapshot hash must be provided");
578
604
  }
579
605
  if (!queryText) {
580
606
  throw new Error("Query text must be provided");
581
607
  }
582
- if (!jwt) {
583
- throw new Error("JWT must be provided");
584
- }
585
608
  if (budgetTokens < 100) {
586
609
  throw new Error("Budget tokens must be at least 100");
587
610
  }
588
611
  const startTime = Date.now();
612
+ const jwt = await this.jwtProvider.getJWT();
589
613
  const queryEndpoint = `${this.apiBase}query`;
590
614
  try {
591
615
  const controller = new AbortController2();
@@ -642,13 +666,11 @@ var RetrievalHttpClient = class {
642
666
  * @returns Snapshot status information
643
667
  * @throws Error on status check failures
644
668
  */
645
- async checkSnapshotStatus(snapshotHash, jwt) {
669
+ async checkSnapshotStatus(snapshotHash) {
646
670
  if (!snapshotHash) {
647
671
  throw new Error("Snapshot hash must be provided");
648
672
  }
649
- if (!jwt) {
650
- throw new Error("JWT must be provided");
651
- }
673
+ const jwt = await this.jwtProvider.getJWT();
652
674
  const statusEndpoint = `${this.apiBase}snapshots/${snapshotHash}/status`;
653
675
  try {
654
676
  const controller = new AbortController2();
@@ -693,10 +715,8 @@ var RetrievalHttpClient = class {
693
715
  * @returns true if cache cleared successfully
694
716
  * @throws Error on cache clear failures
695
717
  */
696
- async clearCache(jwt) {
697
- if (!jwt) {
698
- throw new Error("JWT must be provided");
699
- }
718
+ async clearCache() {
719
+ const jwt = await this.jwtProvider.getJWT();
700
720
  const cacheEndpoint = `${this.apiBase}cache`;
701
721
  try {
702
722
  const controller = new AbortController2();
@@ -731,10 +751,8 @@ var RetrievalHttpClient = class {
731
751
  * @returns Cache statistics
732
752
  * @throws Error on stats retrieval failures
733
753
  */
734
- async getCacheStats(jwt) {
735
- if (!jwt) {
736
- throw new Error("JWT must be provided");
737
- }
754
+ async getCacheStats() {
755
+ const jwt = await this.jwtProvider.getJWT();
738
756
  const statsEndpoint = `${this.apiBase}cache/stats`;
739
757
  try {
740
758
  const controller = new AbortController2();
@@ -780,7 +798,7 @@ var RetrievalHttpClient = class {
780
798
  * @param formatter - Output format "standard" or "compact"
781
799
  * @returns Retrieval results
782
800
  */
783
- async queryWithOptions(snapshotHash, queryText, jwt, budgetTokens = 3e3, flowStrength = 1.5, blendAlpha = 0.8, hopDepth = 2, maxIterations = 12, split = 0.8, formatter = "standard") {
801
+ async queryWithOptions(snapshotHash, queryText, budgetTokens = 3e3, flowStrength = 1.5, blendAlpha = 0.8, hopDepth = 2, maxIterations = 12, split = 0.8, formatter = "standard") {
784
802
  const options = {
785
803
  flow_strength: flowStrength,
786
804
  blend_alpha: blendAlpha,
@@ -789,7 +807,7 @@ var RetrievalHttpClient = class {
789
807
  split,
790
808
  formatter
791
809
  };
792
- return this.query(snapshotHash, queryText, budgetTokens, jwt, options);
810
+ return this.query(snapshotHash, queryText, budgetTokens, options);
793
811
  }
794
812
  /**
795
813
  * Close the HTTP client connection (no-op for fetch)
@@ -803,10 +821,26 @@ init_cjs_shims();
803
821
  var ASTHttpClient = class {
804
822
  /**
805
823
  * Initialize the AST HTTP client
806
- * @param uri - URI/URL for connecting to the HTTP server (e.g., "http://localhost:8003")
807
- * @param timeout - Request timeout in milliseconds (default: 60000)
824
+ * @param config.baseUrl - URI/URL for connecting to the HTTP server (e.g., "http://localhost:8003")
825
+ * @param config.timeout - Request timeout in milliseconds (default: 60000)
826
+ * @param config.jwtProvider - Provider for obtaining JWT tokens
808
827
  */
809
- constructor(uri = "http://localhost:8003", timeout = 6e4) {
828
+ constructor({
829
+ baseUrl = "http://localhost:8003",
830
+ timeout = 6e4,
831
+ jwtProvider
832
+ }) {
833
+ if (!jwtProvider) {
834
+ throw new Error("ASTHttpClient requires a JWT provider");
835
+ }
836
+ this.timeout = timeout;
837
+ this.jwtProvider = jwtProvider;
838
+ this.configureBase(baseUrl);
839
+ }
840
+ updateBaseUrl(baseUrl) {
841
+ this.configureBase(baseUrl);
842
+ }
843
+ configureBase(uri) {
810
844
  let processedUri = uri;
811
845
  if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
812
846
  processedUri = `http://${uri}`;
@@ -817,7 +851,6 @@ var ASTHttpClient = class {
817
851
  } else {
818
852
  this.baseUrl = `${url.protocol}//${url.host}`;
819
853
  }
820
- this.timeout = timeout;
821
854
  if (this.baseUrl.endsWith("/")) {
822
855
  this.apiBase = `${this.baseUrl}api/ast/`;
823
856
  } else {
@@ -826,14 +859,11 @@ var ASTHttpClient = class {
826
859
  }
827
860
  /**
828
861
  * Get file visitor rules in v2 format optimized for Chokidar v4
829
- * @param jwt - JWT token for authorization (required)
830
862
  * @returns Visitor rules with format, include_extensions, include_filenames, exclude_dirnames
831
863
  * @throws Error on HTTP errors or connection errors
832
864
  */
833
- async getVisitorRulesV2(jwt) {
834
- if (!jwt) {
835
- throw new Error("JWT must be provided");
836
- }
865
+ async getVisitorRulesV2() {
866
+ const jwt = await this.jwtProvider.getJWT();
837
867
  const url = `${this.apiBase}visitor-rules`;
838
868
  try {
839
869
  const controller = new AbortController2();
@@ -916,7 +946,7 @@ var ASTHttpClient = class {
916
946
  `(?:^|[\\/])(?:${[...dirs].map(escapeRe).join("|")})(?:[\\/]|$)`,
917
947
  "i"
918
948
  );
919
- return { exts, names, dirRe };
949
+ return { exts, names, dirRe, dirs };
920
950
  }
921
951
  /**
922
952
  * Build Chokidar v4 `ignored` predicate from compiled rules
@@ -926,8 +956,19 @@ var ASTHttpClient = class {
926
956
  static buildIgnoredPredicate(compiled) {
927
957
  return (p, stats) => {
928
958
  const posix = p.replace(/\\/g, "/");
929
- if (compiled.dirRe.test(posix)) return true;
930
- if (stats?.isDirectory?.()) return false;
959
+ const parts = posix.split("/").map((segment) => segment.toLowerCase());
960
+ const isDirectory = stats?.isDirectory?.() ?? false;
961
+ if (isDirectory) {
962
+ const current = parts[parts.length - 1];
963
+ if (compiled.dirs.has(current)) {
964
+ return true;
965
+ }
966
+ return false;
967
+ }
968
+ const parentDirs = parts.slice(0, -1);
969
+ if (parentDirs.some((segment) => compiled.dirs.has(segment))) {
970
+ return true;
971
+ }
931
972
  const base = posix.split("/").pop()?.toLowerCase() || "";
932
973
  if (compiled.names.has(base)) return false;
933
974
  const extIndex = base.lastIndexOf(".");
@@ -943,8 +984,246 @@ var ASTHttpClient = class {
943
984
  }
944
985
  };
945
986
 
987
+ // src/utils/jwt-factory.ts
988
+ init_cjs_shims();
989
+ var DEFAULT_MIN_TTL_MS = 5e3;
990
+ var JWTFactory = class {
991
+ constructor(authClient, sourceToken, options = {}) {
992
+ this.authClient = authClient;
993
+ this.sourceToken = sourceToken;
994
+ if (!sourceToken) {
995
+ throw new Error("JWTFactory requires a non-empty source token");
996
+ }
997
+ this.minTtlMs = options.minTtlMs ?? DEFAULT_MIN_TTL_MS;
998
+ this.onTokenRefreshed = options.onTokenRefreshed;
999
+ }
1000
+ setSourceToken(token) {
1001
+ if (!token) {
1002
+ throw new Error("JWTFactory requires a non-empty source token");
1003
+ }
1004
+ if (token !== this.sourceToken) {
1005
+ this.sourceToken = token;
1006
+ this.cache = void 0;
1007
+ this.currentServerUrl = void 0;
1008
+ }
1009
+ }
1010
+ invalidate() {
1011
+ this.cache = void 0;
1012
+ this.currentServerUrl = void 0;
1013
+ }
1014
+ async getJWT(forceRefresh = false) {
1015
+ const now = Date.now();
1016
+ if (!forceRefresh && this.cache) {
1017
+ if (now < this.cache.expiresAt) {
1018
+ if (now < this.cache.refreshAt) {
1019
+ return this.cache.token;
1020
+ }
1021
+ } else {
1022
+ this.cache = void 0;
1023
+ }
1024
+ }
1025
+ return this.refresh(now, forceRefresh);
1026
+ }
1027
+ async refresh(now, forceRefresh) {
1028
+ if (!this.refreshPromise) {
1029
+ this.refreshPromise = this.fetchNewToken().finally(() => {
1030
+ this.refreshPromise = void 0;
1031
+ });
1032
+ }
1033
+ try {
1034
+ return await this.refreshPromise;
1035
+ } catch (error) {
1036
+ if (!forceRefresh && this.cache && now < this.cache.expiresAt) {
1037
+ console.warn(
1038
+ "Failed to refresh JWT, using cached token until expiry. Reason:",
1039
+ error
1040
+ );
1041
+ return this.cache.token;
1042
+ }
1043
+ throw error;
1044
+ }
1045
+ }
1046
+ async fetchNewToken() {
1047
+ const response = await this.authClient.authenticate(this.sourceToken);
1048
+ const fetchedAt = Date.now();
1049
+ const expiresAt = this.resolveExpiryMs(
1050
+ response.jwt,
1051
+ response.expires_at,
1052
+ fetchedAt
1053
+ );
1054
+ const payload = decodeJWT(response.jwt);
1055
+ const serverUrl = this.extractServerUrl(payload);
1056
+ const halfLife = Math.max((expiresAt - fetchedAt) / 2, this.minTtlMs);
1057
+ const refreshAt = fetchedAt + halfLife;
1058
+ this.cache = {
1059
+ token: response.jwt,
1060
+ expiresAt,
1061
+ refreshAt,
1062
+ fetchedAt,
1063
+ serverUrl
1064
+ };
1065
+ this.currentServerUrl = serverUrl;
1066
+ this.emitTokenRefreshed({
1067
+ token: response.jwt,
1068
+ expiresAt,
1069
+ serverUrl
1070
+ });
1071
+ return response.jwt;
1072
+ }
1073
+ resolveExpiryMs(jwt, expiresAt, referenceTime) {
1074
+ if (expiresAt) {
1075
+ const parsed = Date.parse(expiresAt);
1076
+ if (!Number.isNaN(parsed) && parsed > referenceTime + this.minTtlMs) {
1077
+ return parsed;
1078
+ }
1079
+ }
1080
+ const decoded = decodeJWT(jwt);
1081
+ if (decoded?.exp) {
1082
+ const expMs = decoded.exp * 1e3;
1083
+ if (expMs > referenceTime + this.minTtlMs) {
1084
+ return expMs;
1085
+ }
1086
+ }
1087
+ return referenceTime + Math.max(this.minTtlMs, 6e4);
1088
+ }
1089
+ extractServerUrl(payload) {
1090
+ const possibleUrl = payload?.server_url;
1091
+ if (typeof possibleUrl === "string" && possibleUrl.trim()) {
1092
+ return possibleUrl.trim();
1093
+ }
1094
+ return void 0;
1095
+ }
1096
+ emitTokenRefreshed(info) {
1097
+ if (this.onTokenRefreshed) {
1098
+ try {
1099
+ this.onTokenRefreshed(info);
1100
+ } catch (error) {
1101
+ console.warn("JWTFactory onTokenRefreshed callback failed:", error);
1102
+ }
1103
+ }
1104
+ }
1105
+ getServerUrl() {
1106
+ return this.currentServerUrl ?? this.cache?.serverUrl;
1107
+ }
1108
+ };
1109
+
1110
+ // src/coderule-clients.ts
1111
+ init_cjs_shims();
1112
+ var DEFAULT_AUTH_BASE_URL = "https://r.coderule.ai:16803";
1113
+ var DEFAULT_SERVICE_BASE_URL = "https://s1.coderule.ai:16803";
1114
+ var DEFAULT_TIMEOUTS = {
1115
+ auth: 3e4,
1116
+ ast: 6e4,
1117
+ retrieval: 6e4,
1118
+ sync: 6e4
1119
+ };
1120
+ function resolveOverrides(options) {
1121
+ return {
1122
+ auth: options.auth,
1123
+ ast: options.ast,
1124
+ retrieval: options.retrieval,
1125
+ sync: options.sync
1126
+ };
1127
+ }
1128
+ function resolveTimeout(service, overrides) {
1129
+ return overrides[service]?.timeout ?? DEFAULT_TIMEOUTS[service];
1130
+ }
1131
+ var CoderuleClients = class {
1132
+ constructor(options) {
1133
+ if (!options?.token) {
1134
+ throw new Error("CoderuleClients requires a non-empty token");
1135
+ }
1136
+ const overrides = resolveOverrides(options);
1137
+ const baseUrl = options.baseUrl;
1138
+ const authBase = overrides.auth?.baseUrl ?? baseUrl ?? DEFAULT_AUTH_BASE_URL;
1139
+ const authTimeout = resolveTimeout("auth", overrides);
1140
+ this.auth = new AuthHttpClient(authBase, authTimeout);
1141
+ const userTokenCallback = options.jwtFactory?.onTokenRefreshed;
1142
+ const jwtOptions = {
1143
+ ...options.jwtFactory,
1144
+ onTokenRefreshed: (info) => {
1145
+ userTokenCallback?.(info);
1146
+ if (info.serverUrl) {
1147
+ this.applyServerUrl(info.serverUrl);
1148
+ }
1149
+ }
1150
+ };
1151
+ this.jwtFactory = new JWTFactory(this.auth, options.token, jwtOptions);
1152
+ this.serviceBaseLocked = {
1153
+ ast: Boolean(overrides.ast?.baseUrl),
1154
+ retrieval: Boolean(overrides.retrieval?.baseUrl),
1155
+ sync: Boolean(overrides.sync?.baseUrl)
1156
+ };
1157
+ const defaultServiceBase = baseUrl ?? DEFAULT_SERVICE_BASE_URL;
1158
+ this.ast = new ASTHttpClient({
1159
+ baseUrl: overrides.ast?.baseUrl ?? defaultServiceBase,
1160
+ timeout: resolveTimeout("ast", overrides),
1161
+ jwtProvider: this.jwtFactory
1162
+ });
1163
+ this.retrieval = new RetrievalHttpClient({
1164
+ baseUrl: overrides.retrieval?.baseUrl ?? defaultServiceBase,
1165
+ timeout: resolveTimeout("retrieval", overrides),
1166
+ jwtProvider: this.jwtFactory
1167
+ });
1168
+ this.sync = new SyncHttpClient({
1169
+ baseUrl: overrides.sync?.baseUrl ?? defaultServiceBase,
1170
+ timeout: resolveTimeout("sync", overrides),
1171
+ jwtProvider: this.jwtFactory
1172
+ });
1173
+ const initialServerUrl = this.jwtFactory.getServerUrl();
1174
+ if (initialServerUrl) {
1175
+ this.applyServerUrl(initialServerUrl);
1176
+ }
1177
+ }
1178
+ get jwt() {
1179
+ return this.jwtFactory;
1180
+ }
1181
+ async getJWT(forceRefresh = false) {
1182
+ return this.jwtFactory.getJWT(forceRefresh);
1183
+ }
1184
+ setToken(token) {
1185
+ this.jwtFactory.setSourceToken(token);
1186
+ }
1187
+ close() {
1188
+ this.ast.close();
1189
+ this.retrieval.close();
1190
+ this.sync.close();
1191
+ this.auth.close();
1192
+ }
1193
+ applyServerUrl(serverUrl) {
1194
+ const trimmed = serverUrl.trim();
1195
+ if (!trimmed || this.lastServerUrl === trimmed) {
1196
+ return;
1197
+ }
1198
+ this.lastServerUrl = trimmed;
1199
+ try {
1200
+ if (!this.serviceBaseLocked.ast) {
1201
+ this.ast.updateBaseUrl(trimmed);
1202
+ }
1203
+ } catch (error) {
1204
+ console.warn("Failed to update AST client base URL:", error);
1205
+ }
1206
+ try {
1207
+ if (!this.serviceBaseLocked.retrieval) {
1208
+ this.retrieval.updateBaseUrl(trimmed);
1209
+ }
1210
+ } catch (error) {
1211
+ console.warn("Failed to update Retrieval client base URL:", error);
1212
+ }
1213
+ try {
1214
+ if (!this.serviceBaseLocked.sync) {
1215
+ this.sync.updateBaseUrl(trimmed);
1216
+ }
1217
+ } catch (error) {
1218
+ console.warn("Failed to update Sync client base URL:", error);
1219
+ }
1220
+ }
1221
+ };
1222
+
946
1223
  exports.ASTHttpClient = ASTHttpClient;
947
1224
  exports.AuthHttpClient = AuthHttpClient;
1225
+ exports.CoderuleClients = CoderuleClients;
1226
+ exports.JWTFactory = JWTFactory;
948
1227
  exports.RetrievalHttpClient = RetrievalHttpClient;
949
1228
  exports.SyncHttpClient = SyncHttpClient;
950
1229
  exports.decodeJWT = decodeJWT;