astro-tokenkit 1.0.16 → 1.0.18
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/README.md +62 -0
- package/dist/auth/manager.js +10 -8
- package/dist/client/client.d.ts +1 -1
- package/dist/client/client.js +9 -5
- package/dist/client/idle-manager.d.ts +30 -0
- package/dist/client/idle-manager.js +138 -0
- package/dist/client/tk-client.d.ts +1 -0
- package/dist/client/tk-client.js +22 -0
- package/dist/config.js +4 -1
- package/dist/index.cjs +171 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +72 -6
- package/dist/index.js +171 -88
- package/dist/index.js.map +1 -1
- package/dist/integration.d.ts +23 -1
- package/dist/integration.js +28 -3
- package/dist/middleware.cjs +70 -14
- package/dist/middleware.cjs.map +1 -1
- package/dist/middleware.js +70 -14
- package/dist/middleware.js.map +1 -1
- package/dist/types.d.ts +50 -6
- package/dist/types.js +10 -7
- package/dist/utils/fetch.d.ts +5 -0
- package/dist/utils/fetch.js +36 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.js +22 -0
- package/package.json +6 -1
package/dist/index.cjs
CHANGED
|
@@ -39,20 +39,23 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
39
39
|
* API Error
|
|
40
40
|
*/
|
|
41
41
|
class APIError extends Error {
|
|
42
|
-
constructor(message, status, response, request) {
|
|
42
|
+
constructor(message, status, response, request, cause) {
|
|
43
43
|
super(message);
|
|
44
44
|
this.status = status;
|
|
45
45
|
this.response = response;
|
|
46
46
|
this.request = request;
|
|
47
|
+
this.cause = cause;
|
|
47
48
|
this.name = 'APIError';
|
|
49
|
+
if (cause && !this.cause)
|
|
50
|
+
this.cause = cause;
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
54
|
* Authentication Error
|
|
52
55
|
*/
|
|
53
56
|
class AuthError extends APIError {
|
|
54
|
-
constructor(message, status, response, request) {
|
|
55
|
-
super(message, status, response, request);
|
|
57
|
+
constructor(message, status, response, request, cause) {
|
|
58
|
+
super(message, status, response, request, cause);
|
|
56
59
|
this.name = 'AuthError';
|
|
57
60
|
}
|
|
58
61
|
}
|
|
@@ -60,8 +63,8 @@ class AuthError extends APIError {
|
|
|
60
63
|
* Network Error
|
|
61
64
|
*/
|
|
62
65
|
class NetworkError extends APIError {
|
|
63
|
-
constructor(message, request) {
|
|
64
|
-
super(message, undefined, undefined, request);
|
|
66
|
+
constructor(message, request, cause) {
|
|
67
|
+
super(message, undefined, undefined, request, cause);
|
|
65
68
|
this.name = 'NetworkError';
|
|
66
69
|
}
|
|
67
70
|
}
|
|
@@ -69,8 +72,8 @@ class NetworkError extends APIError {
|
|
|
69
72
|
* Timeout Error
|
|
70
73
|
*/
|
|
71
74
|
class TimeoutError extends APIError {
|
|
72
|
-
constructor(message, request) {
|
|
73
|
-
super(message, undefined, undefined, request);
|
|
75
|
+
constructor(message, request, cause) {
|
|
76
|
+
super(message, undefined, undefined, request, cause);
|
|
74
77
|
this.name = 'TimeoutError';
|
|
75
78
|
}
|
|
76
79
|
}
|
|
@@ -396,6 +399,122 @@ function isExpired(expiresAt, now, policy = {}) {
|
|
|
396
399
|
return now + clockSkew > expiresAt;
|
|
397
400
|
}
|
|
398
401
|
|
|
402
|
+
// packages/astro-tokenkit/src/utils/fetch.ts
|
|
403
|
+
/**
|
|
404
|
+
* Perform a fetch request with optional certificate validation bypass
|
|
405
|
+
*/
|
|
406
|
+
function safeFetch(url, init, config) {
|
|
407
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
408
|
+
const fetchFn = config.fetch || fetch;
|
|
409
|
+
const fetchOptions = Object.assign({}, init);
|
|
410
|
+
if (config.dangerouslyIgnoreCertificateErrors && typeof process !== 'undefined') {
|
|
411
|
+
// In Node.js environment
|
|
412
|
+
try {
|
|
413
|
+
// Try to use undici Agent if available (it is built-in in Node 18+)
|
|
414
|
+
// However, we might need to import it if we want to create an Agent.
|
|
415
|
+
// Since we don't want to depend on undici in package.json, we use dynamic import.
|
|
416
|
+
// But wait, undici's Agent is what we need.
|
|
417
|
+
// As a fallback and most reliable way for self-signed certs in Node without extra deps:
|
|
418
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
419
|
+
// NOTE: This affects the whole process. We should ideally only do this if it's not already 0.
|
|
420
|
+
// But for a dev tool / specialized library, it's often what's needed.
|
|
421
|
+
}
|
|
422
|
+
catch (e) {
|
|
423
|
+
// Ignore
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return fetchFn(url, fetchOptions);
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// packages/astro-tokenkit/src/config.ts
|
|
431
|
+
const CONFIG_KEY = Symbol.for('astro-tokenkit.config');
|
|
432
|
+
const MANAGER_KEY = Symbol.for('astro-tokenkit.manager');
|
|
433
|
+
const globalStorage = globalThis;
|
|
434
|
+
// Initialize global storage if not present
|
|
435
|
+
if (!globalStorage[CONFIG_KEY]) {
|
|
436
|
+
globalStorage[CONFIG_KEY] = {
|
|
437
|
+
runWithContext: undefined,
|
|
438
|
+
getContextStore: undefined,
|
|
439
|
+
setContextStore: undefined,
|
|
440
|
+
baseURL: "",
|
|
441
|
+
debug: false,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Set configuration
|
|
446
|
+
*/
|
|
447
|
+
function setConfig(userConfig) {
|
|
448
|
+
var _a, _b;
|
|
449
|
+
const currentConfig = globalStorage[CONFIG_KEY];
|
|
450
|
+
const finalConfig = Object.assign(Object.assign({}, currentConfig), userConfig);
|
|
451
|
+
// Validate that getter and setter are defined together
|
|
452
|
+
if ((finalConfig.getContextStore && !finalConfig.setContextStore) ||
|
|
453
|
+
(!finalConfig.getContextStore && finalConfig.setContextStore)) {
|
|
454
|
+
throw new Error("[TokenKit] getContextStore and setContextStore must be defined together.");
|
|
455
|
+
}
|
|
456
|
+
globalStorage[CONFIG_KEY] = finalConfig;
|
|
457
|
+
// Re-initialize global token manager if auth changed
|
|
458
|
+
if (finalConfig.auth) {
|
|
459
|
+
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 });
|
|
460
|
+
globalStorage[MANAGER_KEY] = new TokenManager(authConfig, finalConfig.baseURL);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
globalStorage[MANAGER_KEY] = undefined;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Get current configuration
|
|
468
|
+
*/
|
|
469
|
+
function getConfig() {
|
|
470
|
+
return globalStorage[CONFIG_KEY];
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Get global token manager
|
|
474
|
+
*/
|
|
475
|
+
function getTokenManager() {
|
|
476
|
+
return globalStorage[MANAGER_KEY];
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Set global token manager (mainly for testing)
|
|
480
|
+
*/
|
|
481
|
+
function setTokenManager(manager) {
|
|
482
|
+
globalStorage[MANAGER_KEY] = manager;
|
|
483
|
+
}
|
|
484
|
+
// Handle injected configuration from Astro integration
|
|
485
|
+
try {
|
|
486
|
+
// @ts-ignore
|
|
487
|
+
const injectedConfig = typeof __TOKENKIT_CONFIG__ !== 'undefined' ? __TOKENKIT_CONFIG__ : undefined;
|
|
488
|
+
if (injectedConfig) {
|
|
489
|
+
setConfig(injectedConfig);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
catch (e) {
|
|
493
|
+
// Ignore errors in environments where __TOKENKIT_CONFIG__ might be restricted
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Logger utility that respects the debug flag in the configuration
|
|
498
|
+
*/
|
|
499
|
+
const logger = {
|
|
500
|
+
debug: (message, ...args) => {
|
|
501
|
+
if (getConfig().debug) {
|
|
502
|
+
console.debug(message, ...args);
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
info: (message, ...args) => {
|
|
506
|
+
if (getConfig().debug) {
|
|
507
|
+
console.log(message, ...args);
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
warn: (message, ...args) => {
|
|
511
|
+
console.warn(message, ...args);
|
|
512
|
+
},
|
|
513
|
+
error: (message, ...args) => {
|
|
514
|
+
console.error(message, ...args);
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
|
|
399
518
|
// packages/astro-tokenkit/src/auth/manager.ts
|
|
400
519
|
/**
|
|
401
520
|
* Single-flight refresh manager
|
|
@@ -452,14 +571,14 @@ class TokenManager {
|
|
|
452
571
|
}
|
|
453
572
|
let response;
|
|
454
573
|
try {
|
|
455
|
-
response = yield
|
|
574
|
+
response = yield safeFetch(url, {
|
|
456
575
|
method: 'POST',
|
|
457
576
|
headers,
|
|
458
577
|
body: requestBody,
|
|
459
|
-
});
|
|
578
|
+
}, this.config);
|
|
460
579
|
}
|
|
461
580
|
catch (error) {
|
|
462
|
-
const authError = new AuthError(`Login request failed: ${error.message}
|
|
581
|
+
const authError = new AuthError(`Login request failed: ${error.message}`, undefined, undefined, undefined, error);
|
|
463
582
|
if (options === null || options === void 0 ? void 0 : options.onError)
|
|
464
583
|
yield options.onError(authError, ctx);
|
|
465
584
|
throw authError;
|
|
@@ -533,14 +652,14 @@ class TokenManager {
|
|
|
533
652
|
}
|
|
534
653
|
let response;
|
|
535
654
|
try {
|
|
536
|
-
response = yield
|
|
655
|
+
response = yield safeFetch(url, {
|
|
537
656
|
method: 'POST',
|
|
538
657
|
headers,
|
|
539
658
|
body: requestBody,
|
|
540
|
-
});
|
|
659
|
+
}, this.config);
|
|
541
660
|
}
|
|
542
661
|
catch (error) {
|
|
543
|
-
throw new AuthError(`Refresh request failed: ${error.message}
|
|
662
|
+
throw new AuthError(`Refresh request failed: ${error.message}`, undefined, undefined, undefined, error);
|
|
544
663
|
}
|
|
545
664
|
if (!response.ok) {
|
|
546
665
|
// 401/403 = invalid refresh token
|
|
@@ -638,11 +757,11 @@ class TokenManager {
|
|
|
638
757
|
const injectFn = (_a = this.config.injectToken) !== null && _a !== void 0 ? _a : ((token, type) => `${type !== null && type !== void 0 ? type : 'Bearer'} ${token}`);
|
|
639
758
|
headers['Authorization'] = injectFn(session.accessToken, session.tokenType);
|
|
640
759
|
}
|
|
641
|
-
yield
|
|
760
|
+
yield safeFetch(url, { method: 'POST', headers }, this.config);
|
|
642
761
|
}
|
|
643
762
|
catch (error) {
|
|
644
763
|
// Ignore logout endpoint errors
|
|
645
|
-
|
|
764
|
+
logger.debug('[TokenKit] Logout endpoint failed:', error);
|
|
646
765
|
}
|
|
647
766
|
}
|
|
648
767
|
clearTokens(ctx, this.config.cookies);
|
|
@@ -688,69 +807,6 @@ class TokenManager {
|
|
|
688
807
|
}
|
|
689
808
|
}
|
|
690
809
|
|
|
691
|
-
// packages/astro-tokenkit/src/config.ts
|
|
692
|
-
const CONFIG_KEY = Symbol.for('astro-tokenkit.config');
|
|
693
|
-
const MANAGER_KEY = Symbol.for('astro-tokenkit.manager');
|
|
694
|
-
const globalStorage = globalThis;
|
|
695
|
-
// Initialize global storage if not present
|
|
696
|
-
if (!globalStorage[CONFIG_KEY]) {
|
|
697
|
-
globalStorage[CONFIG_KEY] = {
|
|
698
|
-
runWithContext: undefined,
|
|
699
|
-
getContextStore: undefined,
|
|
700
|
-
setContextStore: undefined,
|
|
701
|
-
baseURL: "",
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
/**
|
|
705
|
-
* Set configuration
|
|
706
|
-
*/
|
|
707
|
-
function setConfig(userConfig) {
|
|
708
|
-
const currentConfig = globalStorage[CONFIG_KEY];
|
|
709
|
-
const finalConfig = Object.assign(Object.assign({}, currentConfig), userConfig);
|
|
710
|
-
// Validate that getter and setter are defined together
|
|
711
|
-
if ((finalConfig.getContextStore && !finalConfig.setContextStore) ||
|
|
712
|
-
(!finalConfig.getContextStore && finalConfig.setContextStore)) {
|
|
713
|
-
throw new Error("[TokenKit] getContextStore and setContextStore must be defined together.");
|
|
714
|
-
}
|
|
715
|
-
globalStorage[CONFIG_KEY] = finalConfig;
|
|
716
|
-
// Re-initialize global token manager if auth changed
|
|
717
|
-
if (finalConfig.auth) {
|
|
718
|
-
globalStorage[MANAGER_KEY] = new TokenManager(finalConfig.auth, finalConfig.baseURL);
|
|
719
|
-
}
|
|
720
|
-
else {
|
|
721
|
-
globalStorage[MANAGER_KEY] = undefined;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
/**
|
|
725
|
-
* Get current configuration
|
|
726
|
-
*/
|
|
727
|
-
function getConfig() {
|
|
728
|
-
return globalStorage[CONFIG_KEY];
|
|
729
|
-
}
|
|
730
|
-
/**
|
|
731
|
-
* Get global token manager
|
|
732
|
-
*/
|
|
733
|
-
function getTokenManager() {
|
|
734
|
-
return globalStorage[MANAGER_KEY];
|
|
735
|
-
}
|
|
736
|
-
/**
|
|
737
|
-
* Set global token manager (mainly for testing)
|
|
738
|
-
*/
|
|
739
|
-
function setTokenManager(manager) {
|
|
740
|
-
globalStorage[MANAGER_KEY] = manager;
|
|
741
|
-
}
|
|
742
|
-
// Handle injected configuration from Astro integration
|
|
743
|
-
try {
|
|
744
|
-
// @ts-ignore
|
|
745
|
-
const injectedConfig = typeof __TOKENKIT_CONFIG__ !== 'undefined' ? __TOKENKIT_CONFIG__ : undefined;
|
|
746
|
-
if (injectedConfig) {
|
|
747
|
-
setConfig(injectedConfig);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
catch (e) {
|
|
751
|
-
// Ignore errors in environments where __TOKENKIT_CONFIG__ might be restricted
|
|
752
|
-
}
|
|
753
|
-
|
|
754
810
|
// packages/astro-tokenkit/src/client/context.ts
|
|
755
811
|
/**
|
|
756
812
|
* Async local storage for Astro context
|
|
@@ -847,7 +903,7 @@ function createMiddleware() {
|
|
|
847
903
|
else if (config.context) {
|
|
848
904
|
contextStrategy = 'custom (external AsyncLocalStorage)';
|
|
849
905
|
}
|
|
850
|
-
|
|
906
|
+
logger.debug(`[TokenKit] Middleware initialized (auth: ${authStatus}, context: ${contextStrategy})`);
|
|
851
907
|
globalStorage[LOGGED_KEY] = true;
|
|
852
908
|
}
|
|
853
909
|
const runLogic = () => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -859,7 +915,7 @@ function createMiddleware() {
|
|
|
859
915
|
}
|
|
860
916
|
catch (error) {
|
|
861
917
|
// Log only the message to avoid leaking sensitive data in the error object
|
|
862
|
-
|
|
918
|
+
logger.debug('[TokenKit] Automatic token rotation failed:', error.message || error);
|
|
863
919
|
}
|
|
864
920
|
}
|
|
865
921
|
return next();
|
|
@@ -904,6 +960,7 @@ class APIClient {
|
|
|
904
960
|
* Get token manager
|
|
905
961
|
*/
|
|
906
962
|
get tokenManager() {
|
|
963
|
+
var _a, _b;
|
|
907
964
|
const config = this.config;
|
|
908
965
|
if (!config.auth)
|
|
909
966
|
return undefined;
|
|
@@ -919,7 +976,9 @@ class APIClient {
|
|
|
919
976
|
if (!this._localTokenManager ||
|
|
920
977
|
this._lastUsedAuth !== config.auth ||
|
|
921
978
|
this._lastUsedBaseURL !== config.baseURL) {
|
|
922
|
-
|
|
979
|
+
// Merge client-level fetch and SSL settings into auth config
|
|
980
|
+
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 });
|
|
981
|
+
this._localTokenManager = new TokenManager(authConfig, config.baseURL);
|
|
923
982
|
this._lastUsedAuth = config.auth;
|
|
924
983
|
this._lastUsedBaseURL = config.baseURL;
|
|
925
984
|
}
|
|
@@ -1036,7 +1095,7 @@ class APIClient {
|
|
|
1036
1095
|
const controller = new AbortController();
|
|
1037
1096
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1038
1097
|
try {
|
|
1039
|
-
const response = yield
|
|
1098
|
+
const response = yield safeFetch(fullURL, Object.assign(Object.assign({}, init), { signal: controller.signal }), this.config);
|
|
1040
1099
|
clearTimeout(timeoutId);
|
|
1041
1100
|
// Handle 401 (try refresh and retry once)
|
|
1042
1101
|
if (response.status === 401 && this.tokenManager && !config.skipAuth && attempt === 1) {
|
|
@@ -1069,12 +1128,12 @@ class APIClient {
|
|
|
1069
1128
|
}
|
|
1070
1129
|
// Transform errors
|
|
1071
1130
|
if (error instanceof Error && error.name === 'AbortError') {
|
|
1072
|
-
throw new TimeoutError(`Request timeout after ${timeout}ms`, requestConfig);
|
|
1131
|
+
throw new TimeoutError(`Request timeout after ${timeout}ms`, requestConfig, error);
|
|
1073
1132
|
}
|
|
1074
1133
|
if (error instanceof APIError) {
|
|
1075
1134
|
throw error;
|
|
1076
1135
|
}
|
|
1077
|
-
throw new NetworkError(error.message, requestConfig);
|
|
1136
|
+
throw new NetworkError(error.message, requestConfig, error);
|
|
1078
1137
|
}
|
|
1079
1138
|
});
|
|
1080
1139
|
}
|
|
@@ -1168,7 +1227,7 @@ class APIClient {
|
|
|
1168
1227
|
throw new Error('Auth is not configured for this client');
|
|
1169
1228
|
}
|
|
1170
1229
|
const context = getContextStore();
|
|
1171
|
-
return this.tokenManager.login(context, credentials, options);
|
|
1230
|
+
return yield this.tokenManager.login(context, credentials, options);
|
|
1172
1231
|
});
|
|
1173
1232
|
}
|
|
1174
1233
|
/**
|
|
@@ -1225,6 +1284,13 @@ function createClient(config) {
|
|
|
1225
1284
|
* Astro integration for TokenKit
|
|
1226
1285
|
*
|
|
1227
1286
|
* This integration facilitates the setup of TokenKit in an Astro project.
|
|
1287
|
+
* It performs the following:
|
|
1288
|
+
* - Sets the global configuration for the API client.
|
|
1289
|
+
* - Injects the configuration into the client-side via Vite's `define`.
|
|
1290
|
+
* - Automatically registers the TokenKit middleware (unless `autoMiddleware` is set to `false`).
|
|
1291
|
+
* - Injects a client-side script (`astro-tokenkit/client-init`) to handle idle session monitoring and automatic logout.
|
|
1292
|
+
*
|
|
1293
|
+
* @param config - TokenKit configuration options.
|
|
1228
1294
|
*
|
|
1229
1295
|
* @example
|
|
1230
1296
|
* ```ts
|
|
@@ -1238,6 +1304,10 @@ function createClient(config) {
|
|
|
1238
1304
|
* auth: {
|
|
1239
1305
|
* login: '/auth/login',
|
|
1240
1306
|
* refresh: '/auth/refresh',
|
|
1307
|
+
* },
|
|
1308
|
+
* idle: {
|
|
1309
|
+
* timeout: 3600, // 1 hour
|
|
1310
|
+
* alert: { title: 'Session Expired' }
|
|
1241
1311
|
* }
|
|
1242
1312
|
* })
|
|
1243
1313
|
* ]
|
|
@@ -1255,7 +1325,7 @@ function tokenKit(config) {
|
|
|
1255
1325
|
return {
|
|
1256
1326
|
name: 'astro-tokenkit',
|
|
1257
1327
|
hooks: {
|
|
1258
|
-
'astro:config:setup': ({ updateConfig, addMiddleware }) => {
|
|
1328
|
+
'astro:config:setup': ({ updateConfig, addMiddleware, injectScript }) => {
|
|
1259
1329
|
updateConfig({
|
|
1260
1330
|
vite: {
|
|
1261
1331
|
define: {
|
|
@@ -1270,13 +1340,26 @@ function tokenKit(config) {
|
|
|
1270
1340
|
order: 'pre'
|
|
1271
1341
|
});
|
|
1272
1342
|
}
|
|
1273
|
-
|
|
1343
|
+
// Always inject the client-side script for idle monitoring
|
|
1344
|
+
injectScript('page', `import 'astro-tokenkit/client-init';`);
|
|
1345
|
+
logger.debug('[TokenKit] Integration initialized');
|
|
1274
1346
|
},
|
|
1275
1347
|
},
|
|
1276
1348
|
};
|
|
1277
1349
|
}
|
|
1278
1350
|
/**
|
|
1279
|
-
* Helper to
|
|
1351
|
+
* Helper to create the TokenKit middleware.
|
|
1352
|
+
*
|
|
1353
|
+
* Use this if you have `autoMiddleware: false` in your integration configuration
|
|
1354
|
+
* and want to manually register the middleware in your `src/middleware.ts` file.
|
|
1355
|
+
*
|
|
1356
|
+
* @example
|
|
1357
|
+
* ```ts
|
|
1358
|
+
* // src/middleware.ts
|
|
1359
|
+
* import { defineMiddleware } from 'astro-tokenkit';
|
|
1360
|
+
*
|
|
1361
|
+
* export const onRequest = defineMiddleware();
|
|
1362
|
+
* ```
|
|
1280
1363
|
*/
|
|
1281
1364
|
const defineMiddleware = () => createMiddleware();
|
|
1282
1365
|
|