astro-tokenkit 1.0.16 → 1.0.17

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.d.ts CHANGED
@@ -134,6 +134,10 @@ interface AuthConfig {
134
134
  policy?: RefreshPolicy;
135
135
  /** Cookie configuration */
136
136
  cookies?: CookieConfig;
137
+ /** Custom fetch implementation */
138
+ fetch?: typeof fetch;
139
+ /** Dangerously ignore certificate errors (bypass SSL validation) */
140
+ dangerouslyIgnoreCertificateErrors?: boolean;
137
141
  }
138
142
  /**
139
143
  * Refresh policy
@@ -216,6 +220,12 @@ interface ClientConfig {
216
220
  setContextStore?: (ctx: TokenKitContext) => void;
217
221
  /** Custom context runner */
218
222
  runWithContext?: <T>(ctx: TokenKitContext, fn: () => T) => T;
223
+ /** Custom fetch implementation */
224
+ fetch?: typeof fetch;
225
+ /** Enable debug logging */
226
+ debug?: boolean;
227
+ /** Dangerously ignore certificate errors (bypass SSL validation) */
228
+ dangerouslyIgnoreCertificateErrors?: boolean;
219
229
  }
220
230
  /**
221
231
  * TokenKit Global Configuration
@@ -234,25 +244,26 @@ declare class APIError extends Error {
234
244
  status?: number | undefined;
235
245
  response?: any | undefined;
236
246
  request?: RequestConfig | undefined;
237
- constructor(message: string, status?: number | undefined, response?: any | undefined, request?: RequestConfig | undefined);
247
+ cause?: any | undefined;
248
+ constructor(message: string, status?: number | undefined, response?: any | undefined, request?: RequestConfig | undefined, cause?: any | undefined);
238
249
  }
239
250
  /**
240
251
  * Authentication Error
241
252
  */
242
253
  declare class AuthError extends APIError {
243
- constructor(message: string, status?: number, response?: any, request?: RequestConfig);
254
+ constructor(message: string, status?: number, response?: any, request?: RequestConfig, cause?: any);
244
255
  }
245
256
  /**
246
257
  * Network Error
247
258
  */
248
259
  declare class NetworkError extends APIError {
249
- constructor(message: string, request?: RequestConfig);
260
+ constructor(message: string, request?: RequestConfig, cause?: any);
250
261
  }
251
262
  /**
252
263
  * Timeout Error
253
264
  */
254
265
  declare class TimeoutError extends APIError {
255
- constructor(message: string, request?: RequestConfig);
266
+ constructor(message: string, request?: RequestConfig, cause?: any);
256
267
  }
257
268
 
258
269
  /**
package/dist/index.js CHANGED
@@ -37,20 +37,23 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
37
37
  * API Error
38
38
  */
39
39
  class APIError extends Error {
40
- constructor(message, status, response, request) {
40
+ constructor(message, status, response, request, cause) {
41
41
  super(message);
42
42
  this.status = status;
43
43
  this.response = response;
44
44
  this.request = request;
45
+ this.cause = cause;
45
46
  this.name = 'APIError';
47
+ if (cause && !this.cause)
48
+ this.cause = cause;
46
49
  }
47
50
  }
48
51
  /**
49
52
  * Authentication Error
50
53
  */
51
54
  class AuthError extends APIError {
52
- constructor(message, status, response, request) {
53
- super(message, status, response, request);
55
+ constructor(message, status, response, request, cause) {
56
+ super(message, status, response, request, cause);
54
57
  this.name = 'AuthError';
55
58
  }
56
59
  }
@@ -58,8 +61,8 @@ class AuthError extends APIError {
58
61
  * Network Error
59
62
  */
60
63
  class NetworkError extends APIError {
61
- constructor(message, request) {
62
- super(message, undefined, undefined, request);
64
+ constructor(message, request, cause) {
65
+ super(message, undefined, undefined, request, cause);
63
66
  this.name = 'NetworkError';
64
67
  }
65
68
  }
@@ -67,8 +70,8 @@ class NetworkError extends APIError {
67
70
  * Timeout Error
68
71
  */
69
72
  class TimeoutError extends APIError {
70
- constructor(message, request) {
71
- super(message, undefined, undefined, request);
73
+ constructor(message, request, cause) {
74
+ super(message, undefined, undefined, request, cause);
72
75
  this.name = 'TimeoutError';
73
76
  }
74
77
  }
@@ -394,6 +397,122 @@ function isExpired(expiresAt, now, policy = {}) {
394
397
  return now + clockSkew > expiresAt;
395
398
  }
396
399
 
400
+ // packages/astro-tokenkit/src/utils/fetch.ts
401
+ /**
402
+ * Perform a fetch request with optional certificate validation bypass
403
+ */
404
+ function safeFetch(url, init, config) {
405
+ return __awaiter(this, void 0, void 0, function* () {
406
+ const fetchFn = config.fetch || fetch;
407
+ const fetchOptions = Object.assign({}, init);
408
+ if (config.dangerouslyIgnoreCertificateErrors && typeof process !== 'undefined') {
409
+ // In Node.js environment
410
+ try {
411
+ // Try to use undici Agent if available (it is built-in in Node 18+)
412
+ // However, we might need to import it if we want to create an Agent.
413
+ // Since we don't want to depend on undici in package.json, we use dynamic import.
414
+ // But wait, undici's Agent is what we need.
415
+ // As a fallback and most reliable way for self-signed certs in Node without extra deps:
416
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
417
+ // NOTE: This affects the whole process. We should ideally only do this if it's not already 0.
418
+ // But for a dev tool / specialized library, it's often what's needed.
419
+ }
420
+ catch (e) {
421
+ // Ignore
422
+ }
423
+ }
424
+ return fetchFn(url, fetchOptions);
425
+ });
426
+ }
427
+
428
+ // packages/astro-tokenkit/src/config.ts
429
+ const CONFIG_KEY = Symbol.for('astro-tokenkit.config');
430
+ const MANAGER_KEY = Symbol.for('astro-tokenkit.manager');
431
+ const globalStorage = globalThis;
432
+ // Initialize global storage if not present
433
+ if (!globalStorage[CONFIG_KEY]) {
434
+ globalStorage[CONFIG_KEY] = {
435
+ runWithContext: undefined,
436
+ getContextStore: undefined,
437
+ setContextStore: undefined,
438
+ baseURL: "",
439
+ debug: false,
440
+ };
441
+ }
442
+ /**
443
+ * Set configuration
444
+ */
445
+ function setConfig(userConfig) {
446
+ var _a, _b;
447
+ const currentConfig = globalStorage[CONFIG_KEY];
448
+ const finalConfig = Object.assign(Object.assign({}, currentConfig), userConfig);
449
+ // Validate that getter and setter are defined together
450
+ if ((finalConfig.getContextStore && !finalConfig.setContextStore) ||
451
+ (!finalConfig.getContextStore && finalConfig.setContextStore)) {
452
+ throw new Error("[TokenKit] getContextStore and setContextStore must be defined together.");
453
+ }
454
+ globalStorage[CONFIG_KEY] = finalConfig;
455
+ // Re-initialize global token manager if auth changed
456
+ if (finalConfig.auth) {
457
+ const authConfig = Object.assign(Object.assign({}, finalConfig.auth), { fetch: (_a = finalConfig.auth.fetch) !== null && _a !== void 0 ? _a : finalConfig.fetch, dangerouslyIgnoreCertificateErrors: (_b = finalConfig.auth.dangerouslyIgnoreCertificateErrors) !== null && _b !== void 0 ? _b : finalConfig.dangerouslyIgnoreCertificateErrors });
458
+ globalStorage[MANAGER_KEY] = new TokenManager(authConfig, finalConfig.baseURL);
459
+ }
460
+ else {
461
+ globalStorage[MANAGER_KEY] = undefined;
462
+ }
463
+ }
464
+ /**
465
+ * Get current configuration
466
+ */
467
+ function getConfig() {
468
+ return globalStorage[CONFIG_KEY];
469
+ }
470
+ /**
471
+ * Get global token manager
472
+ */
473
+ function getTokenManager() {
474
+ return globalStorage[MANAGER_KEY];
475
+ }
476
+ /**
477
+ * Set global token manager (mainly for testing)
478
+ */
479
+ function setTokenManager(manager) {
480
+ globalStorage[MANAGER_KEY] = manager;
481
+ }
482
+ // Handle injected configuration from Astro integration
483
+ try {
484
+ // @ts-ignore
485
+ const injectedConfig = typeof __TOKENKIT_CONFIG__ !== 'undefined' ? __TOKENKIT_CONFIG__ : undefined;
486
+ if (injectedConfig) {
487
+ setConfig(injectedConfig);
488
+ }
489
+ }
490
+ catch (e) {
491
+ // Ignore errors in environments where __TOKENKIT_CONFIG__ might be restricted
492
+ }
493
+
494
+ /**
495
+ * Logger utility that respects the debug flag in the configuration
496
+ */
497
+ const logger = {
498
+ debug: (message, ...args) => {
499
+ if (getConfig().debug) {
500
+ console.debug(message, ...args);
501
+ }
502
+ },
503
+ info: (message, ...args) => {
504
+ if (getConfig().debug) {
505
+ console.log(message, ...args);
506
+ }
507
+ },
508
+ warn: (message, ...args) => {
509
+ console.warn(message, ...args);
510
+ },
511
+ error: (message, ...args) => {
512
+ console.error(message, ...args);
513
+ }
514
+ };
515
+
397
516
  // packages/astro-tokenkit/src/auth/manager.ts
398
517
  /**
399
518
  * Single-flight refresh manager
@@ -450,14 +569,14 @@ class TokenManager {
450
569
  }
451
570
  let response;
452
571
  try {
453
- response = yield fetch(url, {
572
+ response = yield safeFetch(url, {
454
573
  method: 'POST',
455
574
  headers,
456
575
  body: requestBody,
457
- });
576
+ }, this.config);
458
577
  }
459
578
  catch (error) {
460
- const authError = new AuthError(`Login request failed: ${error.message}`);
579
+ const authError = new AuthError(`Login request failed: ${error.message}`, undefined, undefined, undefined, error);
461
580
  if (options === null || options === void 0 ? void 0 : options.onError)
462
581
  yield options.onError(authError, ctx);
463
582
  throw authError;
@@ -531,14 +650,14 @@ class TokenManager {
531
650
  }
532
651
  let response;
533
652
  try {
534
- response = yield fetch(url, {
653
+ response = yield safeFetch(url, {
535
654
  method: 'POST',
536
655
  headers,
537
656
  body: requestBody,
538
- });
657
+ }, this.config);
539
658
  }
540
659
  catch (error) {
541
- throw new AuthError(`Refresh request failed: ${error.message}`);
660
+ throw new AuthError(`Refresh request failed: ${error.message}`, undefined, undefined, undefined, error);
542
661
  }
543
662
  if (!response.ok) {
544
663
  // 401/403 = invalid refresh token
@@ -636,11 +755,11 @@ class TokenManager {
636
755
  const injectFn = (_a = this.config.injectToken) !== null && _a !== void 0 ? _a : ((token, type) => `${type !== null && type !== void 0 ? type : 'Bearer'} ${token}`);
637
756
  headers['Authorization'] = injectFn(session.accessToken, session.tokenType);
638
757
  }
639
- yield fetch(url, { method: 'POST', headers });
758
+ yield safeFetch(url, { method: 'POST', headers }, this.config);
640
759
  }
641
760
  catch (error) {
642
761
  // Ignore logout endpoint errors
643
- console.warn('[TokenKit] Logout endpoint failed:', error);
762
+ logger.debug('[TokenKit] Logout endpoint failed:', error);
644
763
  }
645
764
  }
646
765
  clearTokens(ctx, this.config.cookies);
@@ -686,69 +805,6 @@ class TokenManager {
686
805
  }
687
806
  }
688
807
 
689
- // packages/astro-tokenkit/src/config.ts
690
- const CONFIG_KEY = Symbol.for('astro-tokenkit.config');
691
- const MANAGER_KEY = Symbol.for('astro-tokenkit.manager');
692
- const globalStorage = globalThis;
693
- // Initialize global storage if not present
694
- if (!globalStorage[CONFIG_KEY]) {
695
- globalStorage[CONFIG_KEY] = {
696
- runWithContext: undefined,
697
- getContextStore: undefined,
698
- setContextStore: undefined,
699
- baseURL: "",
700
- };
701
- }
702
- /**
703
- * Set configuration
704
- */
705
- function setConfig(userConfig) {
706
- const currentConfig = globalStorage[CONFIG_KEY];
707
- const finalConfig = Object.assign(Object.assign({}, currentConfig), userConfig);
708
- // Validate that getter and setter are defined together
709
- if ((finalConfig.getContextStore && !finalConfig.setContextStore) ||
710
- (!finalConfig.getContextStore && finalConfig.setContextStore)) {
711
- throw new Error("[TokenKit] getContextStore and setContextStore must be defined together.");
712
- }
713
- globalStorage[CONFIG_KEY] = finalConfig;
714
- // Re-initialize global token manager if auth changed
715
- if (finalConfig.auth) {
716
- globalStorage[MANAGER_KEY] = new TokenManager(finalConfig.auth, finalConfig.baseURL);
717
- }
718
- else {
719
- globalStorage[MANAGER_KEY] = undefined;
720
- }
721
- }
722
- /**
723
- * Get current configuration
724
- */
725
- function getConfig() {
726
- return globalStorage[CONFIG_KEY];
727
- }
728
- /**
729
- * Get global token manager
730
- */
731
- function getTokenManager() {
732
- return globalStorage[MANAGER_KEY];
733
- }
734
- /**
735
- * Set global token manager (mainly for testing)
736
- */
737
- function setTokenManager(manager) {
738
- globalStorage[MANAGER_KEY] = manager;
739
- }
740
- // Handle injected configuration from Astro integration
741
- try {
742
- // @ts-ignore
743
- const injectedConfig = typeof __TOKENKIT_CONFIG__ !== 'undefined' ? __TOKENKIT_CONFIG__ : undefined;
744
- if (injectedConfig) {
745
- setConfig(injectedConfig);
746
- }
747
- }
748
- catch (e) {
749
- // Ignore errors in environments where __TOKENKIT_CONFIG__ might be restricted
750
- }
751
-
752
808
  // packages/astro-tokenkit/src/client/context.ts
753
809
  /**
754
810
  * Async local storage for Astro context
@@ -845,7 +901,7 @@ function createMiddleware() {
845
901
  else if (config.context) {
846
902
  contextStrategy = 'custom (external AsyncLocalStorage)';
847
903
  }
848
- console.log(`[TokenKit] Middleware initialized (auth: ${authStatus}, context: ${contextStrategy})`);
904
+ logger.debug(`[TokenKit] Middleware initialized (auth: ${authStatus}, context: ${contextStrategy})`);
849
905
  globalStorage[LOGGED_KEY] = true;
850
906
  }
851
907
  const runLogic = () => __awaiter(this, void 0, void 0, function* () {
@@ -857,7 +913,7 @@ function createMiddleware() {
857
913
  }
858
914
  catch (error) {
859
915
  // Log only the message to avoid leaking sensitive data in the error object
860
- console.error('[TokenKit] Automatic token rotation failed:', error.message || error);
916
+ logger.debug('[TokenKit] Automatic token rotation failed:', error.message || error);
861
917
  }
862
918
  }
863
919
  return next();
@@ -902,6 +958,7 @@ class APIClient {
902
958
  * Get token manager
903
959
  */
904
960
  get tokenManager() {
961
+ var _a, _b;
905
962
  const config = this.config;
906
963
  if (!config.auth)
907
964
  return undefined;
@@ -917,7 +974,9 @@ class APIClient {
917
974
  if (!this._localTokenManager ||
918
975
  this._lastUsedAuth !== config.auth ||
919
976
  this._lastUsedBaseURL !== config.baseURL) {
920
- this._localTokenManager = new TokenManager(config.auth, config.baseURL);
977
+ // Merge client-level fetch and SSL settings into auth config
978
+ const authConfig = Object.assign(Object.assign({}, config.auth), { fetch: (_a = config.auth.fetch) !== null && _a !== void 0 ? _a : config.fetch, dangerouslyIgnoreCertificateErrors: (_b = config.auth.dangerouslyIgnoreCertificateErrors) !== null && _b !== void 0 ? _b : config.dangerouslyIgnoreCertificateErrors });
979
+ this._localTokenManager = new TokenManager(authConfig, config.baseURL);
921
980
  this._lastUsedAuth = config.auth;
922
981
  this._lastUsedBaseURL = config.baseURL;
923
982
  }
@@ -1034,7 +1093,7 @@ class APIClient {
1034
1093
  const controller = new AbortController();
1035
1094
  const timeoutId = setTimeout(() => controller.abort(), timeout);
1036
1095
  try {
1037
- const response = yield fetch(fullURL, Object.assign(Object.assign({}, init), { signal: controller.signal }));
1096
+ const response = yield safeFetch(fullURL, Object.assign(Object.assign({}, init), { signal: controller.signal }), this.config);
1038
1097
  clearTimeout(timeoutId);
1039
1098
  // Handle 401 (try refresh and retry once)
1040
1099
  if (response.status === 401 && this.tokenManager && !config.skipAuth && attempt === 1) {
@@ -1067,12 +1126,12 @@ class APIClient {
1067
1126
  }
1068
1127
  // Transform errors
1069
1128
  if (error instanceof Error && error.name === 'AbortError') {
1070
- throw new TimeoutError(`Request timeout after ${timeout}ms`, requestConfig);
1129
+ throw new TimeoutError(`Request timeout after ${timeout}ms`, requestConfig, error);
1071
1130
  }
1072
1131
  if (error instanceof APIError) {
1073
1132
  throw error;
1074
1133
  }
1075
- throw new NetworkError(error.message, requestConfig);
1134
+ throw new NetworkError(error.message, requestConfig, error);
1076
1135
  }
1077
1136
  });
1078
1137
  }
@@ -1268,7 +1327,7 @@ function tokenKit(config) {
1268
1327
  order: 'pre'
1269
1328
  });
1270
1329
  }
1271
- console.log('[TokenKit] Integration initialized');
1330
+ logger.debug('[TokenKit] Integration initialized');
1272
1331
  },
1273
1332
  },
1274
1333
  };