react-token-manager 1.0.2 → 1.0.3

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 CHANGED
@@ -19,7 +19,6 @@ import { configureTokenManager } from 'react-token-manager'
19
19
 
20
20
  configureTokenManager({
21
21
  storage: 'localStorage', // 'localStorage' | 'sessionStorage' | 'cookie'
22
- tokenKey: 'access_token', // default: 'access_token'
23
22
  })
24
23
  ```
25
24
  ## Using the Hook useTokenManager
@@ -28,18 +27,33 @@ configureTokenManager({
28
27
  import { useTokenManager } from 'react-token-manager'
29
28
 
30
29
  export default function Dashboard() {
31
- const { token, setToken, removeToken, isExpired, decode } = useTokenManager()
30
+ const { setTokens, getTokens, removeTokens, decodeToken, isExpired } = useTokenManager()
32
31
 
33
- const handleLogin = () => setToken('your.jwt.token.here')
34
- const handleLogout = () => removeToken()
32
+ // Set multiple tokens at once
33
+ setTokens({
34
+ access_token: 'abc123',
35
+ refresh_token: 'xyz789',
36
+ })
37
+
38
+ // Get multiple tokens
39
+ const tokens = getTokens(['access_token', 'refresh_token'])
40
+ console.log(tokens.access_token) // 'abc123'
41
+ console.log(tokens.refresh_token) // 'xyz789'
42
+
43
+ // Decode a token
44
+ const payload = decodeToken(tokens.access_token!)
45
+
46
+ // Check if a token is expired
47
+ console.log(isExpired(tokens.access_token!))
48
+
49
+ // Remove multiple tokens
50
+ removeTokens(['access_token', 'refresh_token'])
35
51
 
36
52
  return (
37
53
  <div>
38
- <p>Token: {token}</p>
39
- <p>Expired? {isExpired() ? 'Yes' : 'No'}</p>
40
- <p>Decoded Payload: {JSON.stringify(decode())}</p>
41
- <button onClick={handleLogin}>Login</button>
42
- <button onClick={handleLogout}>Logout</button>
54
+ <p>Access Token: {tokens.access_token}</p>
55
+ <p>Refresh Token: {tokens.refresh_token}</p>
56
+ <p>Decoded Payload: {JSON.stringify(payload)}</p>
43
57
  </div>
44
58
  )
45
59
  }
@@ -52,13 +66,25 @@ You can override storage or tokenKey per hook if needed.
52
66
  ```bash
53
67
  import { TokenManager } from 'react-token-manager'
54
68
 
55
- const manager = new TokenManager({ storage: 'cookie', tokenKey: 'access_token' })
69
+ const manager = new TokenManager({ storage: 'cookie' })
70
+
71
+ // Set multiple tokens
72
+ manager.set({
73
+ access_token: 'abc123',
74
+ refresh_token: 'xyz789',
75
+ })
76
+
77
+ // Get multiple tokens
78
+ const tokens = manager.get(['access_token', 'refresh_token'])
79
+ console.log(tokens.access_token) // 'abc123'
80
+ console.log(tokens.refresh_token) // 'xyz789'
81
+
82
+ // Remove multiple tokens
83
+ manager.remove(['access_token', 'refresh_token'])
56
84
 
57
- manager.set('your.jwt.token')
58
- console.log(manager.get())
59
- console.log(manager.decode()) // decoded JWT payload
60
- console.log(manager.isExpired())
61
- manager.remove()
85
+ // Decode and check expiration of a single token
86
+ console.log(manager.decode(tokens.access_token!))
87
+ console.log(manager.isExpired(tokens.access_token!))
62
88
  ```
63
89
 
64
90
  ## API Reference
@@ -70,36 +96,34 @@ Set global options.
70
96
  ```bash
71
97
  {
72
98
  storage?: 'localStorage' | 'sessionStorage' | 'cookie';
73
- tokenKey?: string;
74
99
  }
75
100
 
101
+
76
102
  useTokenManager(options?: TokenManagerOptions)
77
103
 
78
104
  Returns:
105
+ setTokens(tokens: Record<string, string>) // Set multiple tokens
79
106
 
80
- token: string | null current token
107
+ getTokens(keys: string | string[]) // Get multiple tokens
81
108
 
82
- setToken(value: string) set a new token
109
+ removeTokens(keys: string | string[]) // Remove multiple tokens
83
110
 
84
- removeToken() remove the token
111
+ decodeToken<T = unknown>(token: string) // Decode a single token
85
112
 
86
- isExpired(): boolean check expiration
113
+ isExpired(token: string) // Check if a token is expired
87
114
 
88
- decode<T>(): T | null — decode JWT payload
89
115
 
90
116
  TokenManager Class Methods
117
+ set(tokens: Record<string, string>) // Store multiple tokens
91
118
 
92
- set(token: string) store token
119
+ get(keys: string | string[]) // Retrieve multiple tokens
93
120
 
94
- get(): string | null retrieve token
121
+ remove(keys: string | string[]) // Delete multiple tokens
95
122
 
96
- remove() delete token
123
+ decode<T = unknown>(token: string) // Decode a single token
97
124
 
98
- decode<T = unknown>(): T | null decode JWT payload
125
+ isExpired(token: string) // Check if a token is expired
99
126
 
100
- isExpired(): boolean — check if token is expired
101
-
102
- getValid(): string | null — get token only if valid
103
127
 
104
128
  ```
105
129
 
@@ -108,25 +132,31 @@ TokenManager Class Methods
108
132
  Multiple Tokens
109
133
 
110
134
  ```bash
111
- const { token: accessToken, setToken: setAccess } = useTokenManager({ tokenKey: 'access_token' })
112
- const { token: refreshToken, setToken: setRefresh } = useTokenManager({ tokenKey: 'refresh_token' })
135
+ const { setTokens, getTokens } = useTokenManager()
136
+
137
+ setTokens({
138
+ access_token: 'abc',
139
+ refresh_token: 'xyz',
140
+ })
113
141
 
114
- setAccess('abc')
115
- setRefresh('xyz')
142
+ const tokens = getTokens(['access_token', 'refresh_token'])
143
+ console.log(tokens.access_token) // 'abc'
144
+ console.log(tokens.refresh_token) // 'xyz'
116
145
  ```
117
146
 
118
147
  ##Using Cookies
119
148
  ```bash
120
- configureTokenManager({ storage: 'cookie', tokenKey: 'access_token' })
149
+ configureTokenManager({ storage: 'cookie' })
121
150
  ```
122
151
 
123
152
  Checking Expiry Before API Call
124
153
 
125
154
  ```bash
126
- const manager = useTokenManager()
155
+ const { getTokens, isExpired } = useTokenManager()
156
+ const { access_token } = getTokens(['access_token'])
127
157
 
128
- if (!manager.isExpired()) {
129
- callApi(manager.token)
158
+ if (!isExpired(access_token!)) {
159
+ callApi(access_token)
130
160
  }
131
161
  ```
132
162
 
package/dist/index.d.mts CHANGED
@@ -1,28 +1,34 @@
1
1
  type StorageType = 'localStorage' | 'sessionStorage' | 'cookie';
2
2
  interface TokenManagerOptions {
3
3
  storage?: StorageType;
4
- tokenKey?: string;
5
4
  }
6
5
  declare const configureTokenManager: (options: TokenManagerOptions) => void;
7
6
  declare class TokenManager {
8
7
  private storage;
9
- private tokenKey;
10
8
  constructor(options?: TokenManagerOptions);
11
- set(token: string): void;
12
- get(): string | null;
13
- remove(): void;
14
- decode<T = unknown>(): T | null;
15
- isExpired(): boolean;
16
- getValid(): string | null;
9
+ /** Set multiple tokens at once */
10
+ set(tokens: Record<string, string>): void;
11
+ /** Get single token by key or all tokens in an array of keys */
12
+ get(keys: string | string[]): Record<string, string | null>;
13
+ /** Remove multiple tokens by keys */
14
+ remove(keys: string | string[]): void;
15
+ /** Decode a single token by key */
16
+ decode<T = unknown>(token: string): T | null;
17
+ /** Check if a token is expired */
18
+ isExpired(token: string): boolean;
17
19
  }
18
20
 
19
- interface UseTokenManagerReturn {
20
- token: string | null;
21
- setToken: (value: string) => void;
22
- removeToken: () => void;
23
- isExpired: () => boolean;
24
- decode: <T = unknown>() => T | null;
25
- }
26
- declare const useTokenManager: (options?: TokenManagerOptions) => UseTokenManagerReturn;
21
+ declare const useTokenManager: () => {
22
+ /** Set multiple tokens */
23
+ setTokens: (tokens: Record<string, string>) => void;
24
+ /** Get multiple tokens by keys */
25
+ getTokens: (keys: string | string[]) => Record<string, string | null>;
26
+ /** Remove multiple tokens by keys */
27
+ removeTokens: (keys: string | string[]) => void;
28
+ /** Decode a single token */
29
+ decodeToken: <T = unknown>(token: string) => T | null;
30
+ /** Check expiration of a single token */
31
+ isExpired: (token: string) => boolean;
32
+ };
27
33
 
28
- export { type StorageType, TokenManager, type TokenManagerOptions, type UseTokenManagerReturn, configureTokenManager, useTokenManager };
34
+ export { type StorageType, TokenManager, type TokenManagerOptions, configureTokenManager, useTokenManager };
package/dist/index.d.ts CHANGED
@@ -1,28 +1,34 @@
1
1
  type StorageType = 'localStorage' | 'sessionStorage' | 'cookie';
2
2
  interface TokenManagerOptions {
3
3
  storage?: StorageType;
4
- tokenKey?: string;
5
4
  }
6
5
  declare const configureTokenManager: (options: TokenManagerOptions) => void;
7
6
  declare class TokenManager {
8
7
  private storage;
9
- private tokenKey;
10
8
  constructor(options?: TokenManagerOptions);
11
- set(token: string): void;
12
- get(): string | null;
13
- remove(): void;
14
- decode<T = unknown>(): T | null;
15
- isExpired(): boolean;
16
- getValid(): string | null;
9
+ /** Set multiple tokens at once */
10
+ set(tokens: Record<string, string>): void;
11
+ /** Get single token by key or all tokens in an array of keys */
12
+ get(keys: string | string[]): Record<string, string | null>;
13
+ /** Remove multiple tokens by keys */
14
+ remove(keys: string | string[]): void;
15
+ /** Decode a single token by key */
16
+ decode<T = unknown>(token: string): T | null;
17
+ /** Check if a token is expired */
18
+ isExpired(token: string): boolean;
17
19
  }
18
20
 
19
- interface UseTokenManagerReturn {
20
- token: string | null;
21
- setToken: (value: string) => void;
22
- removeToken: () => void;
23
- isExpired: () => boolean;
24
- decode: <T = unknown>() => T | null;
25
- }
26
- declare const useTokenManager: (options?: TokenManagerOptions) => UseTokenManagerReturn;
21
+ declare const useTokenManager: () => {
22
+ /** Set multiple tokens */
23
+ setTokens: (tokens: Record<string, string>) => void;
24
+ /** Get multiple tokens by keys */
25
+ getTokens: (keys: string | string[]) => Record<string, string | null>;
26
+ /** Remove multiple tokens by keys */
27
+ removeTokens: (keys: string | string[]) => void;
28
+ /** Decode a single token */
29
+ decodeToken: <T = unknown>(token: string) => T | null;
30
+ /** Check expiration of a single token */
31
+ isExpired: (token: string) => boolean;
32
+ };
27
33
 
28
- export { type StorageType, TokenManager, type TokenManagerOptions, type UseTokenManagerReturn, configureTokenManager, useTokenManager };
34
+ export { type StorageType, TokenManager, type TokenManagerOptions, configureTokenManager, useTokenManager };
package/dist/index.js CHANGED
@@ -40,8 +40,7 @@ module.exports = __toCommonJS(index_exports);
40
40
  var jwtDecodeModule = __toESM(require("jwt-decode"));
41
41
  var jwtDecode = jwtDecodeModule.default || jwtDecodeModule;
42
42
  var globalOptions = {
43
- storage: "localStorage",
44
- tokenKey: "access_token"
43
+ storage: "localStorage"
45
44
  };
46
45
  var configureTokenManager = (options) => {
47
46
  globalOptions = { ...globalOptions, ...options };
@@ -50,26 +49,42 @@ var TokenManager = class {
50
49
  constructor(options) {
51
50
  const opts = options || globalOptions;
52
51
  this.storage = opts.storage || "localStorage";
53
- this.tokenKey = opts.tokenKey || "access_token";
54
52
  }
55
- set(token) {
56
- if (this.storage === "localStorage") localStorage.setItem(this.tokenKey, token);
57
- else if (this.storage === "sessionStorage") sessionStorage.setItem(this.tokenKey, token);
58
- else document.cookie = `${this.tokenKey}=${token}; path=/`;
53
+ /** Set multiple tokens at once */
54
+ set(tokens) {
55
+ Object.entries(tokens).forEach(([key, value]) => {
56
+ if (this.storage === "localStorage") localStorage.setItem(key, value);
57
+ else if (this.storage === "sessionStorage") sessionStorage.setItem(key, value);
58
+ else document.cookie = `${key}=${value}; path=/`;
59
+ });
59
60
  }
60
- get() {
61
- if (this.storage === "localStorage") return localStorage.getItem(this.tokenKey);
62
- if (this.storage === "sessionStorage") return sessionStorage.getItem(this.tokenKey);
63
- const match = document.cookie.match(new RegExp("(^| )" + this.tokenKey + "=([^;]+)"));
64
- return match ? match[2] : null;
61
+ /** Get single token by key or all tokens in an array of keys */
62
+ get(keys) {
63
+ const keyArray = Array.isArray(keys) ? keys : [keys];
64
+ const result = {};
65
+ keyArray.forEach((key) => {
66
+ let value = null;
67
+ if (this.storage === "localStorage") value = localStorage.getItem(key);
68
+ else if (this.storage === "sessionStorage") value = sessionStorage.getItem(key);
69
+ else {
70
+ const match = document.cookie.match(new RegExp("(^| )" + key + "=([^;]+)"));
71
+ value = match ? match[2] : null;
72
+ }
73
+ result[key] = value;
74
+ });
75
+ return result;
65
76
  }
66
- remove() {
67
- if (this.storage === "localStorage") localStorage.removeItem(this.tokenKey);
68
- else if (this.storage === "sessionStorage") sessionStorage.removeItem(this.tokenKey);
69
- else document.cookie = `${this.tokenKey}=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
77
+ /** Remove multiple tokens by keys */
78
+ remove(keys) {
79
+ const keyArray = Array.isArray(keys) ? keys : [keys];
80
+ keyArray.forEach((key) => {
81
+ if (this.storage === "localStorage") localStorage.removeItem(key);
82
+ else if (this.storage === "sessionStorage") sessionStorage.removeItem(key);
83
+ else document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
84
+ });
70
85
  }
71
- decode() {
72
- const token = this.get();
86
+ /** Decode a single token by key */
87
+ decode(token) {
73
88
  if (!token) return null;
74
89
  try {
75
90
  return jwtDecode(token);
@@ -77,38 +92,29 @@ var TokenManager = class {
77
92
  return null;
78
93
  }
79
94
  }
80
- isExpired() {
81
- const decoded = this.decode();
95
+ /** Check if a token is expired */
96
+ isExpired(token) {
97
+ const decoded = this.decode(token);
82
98
  if (!decoded || !decoded.exp) return true;
83
99
  return Date.now() >= decoded.exp * 1e3;
84
100
  }
85
- getValid() {
86
- return this.isExpired() ? null : this.get();
87
- }
88
101
  };
89
102
 
90
103
  // src/hook.ts
91
104
  var import_react = require("react");
92
- var useTokenManager = (options) => {
93
- const manager = new TokenManager(options);
94
- const [token, setTokenState] = (0, import_react.useState)(null);
95
- (0, import_react.useEffect)(() => {
96
- setTokenState(manager.getValid());
97
- }, []);
98
- const setToken = (value) => {
99
- manager.set(value);
100
- setTokenState(value);
101
- };
102
- const removeToken = () => {
103
- manager.remove();
104
- setTokenState(null);
105
- };
105
+ var useTokenManager = () => {
106
+ const manager = (0, import_react.useMemo)(() => new TokenManager(), []);
106
107
  return {
107
- token,
108
- setToken,
109
- removeToken,
110
- isExpired: () => manager.isExpired(),
111
- decode: () => manager.decode()
108
+ /** Set multiple tokens */
109
+ setTokens: (tokens) => manager.set(tokens),
110
+ /** Get multiple tokens by keys */
111
+ getTokens: (keys) => manager.get(keys),
112
+ /** Remove multiple tokens by keys */
113
+ removeTokens: (keys) => manager.remove(keys),
114
+ /** Decode a single token */
115
+ decodeToken: (token) => manager.decode(token),
116
+ /** Check expiration of a single token */
117
+ isExpired: (token) => manager.isExpired(token)
112
118
  };
113
119
  };
114
120
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -2,8 +2,7 @@
2
2
  import * as jwtDecodeModule from "jwt-decode";
3
3
  var jwtDecode = jwtDecodeModule.default || jwtDecodeModule;
4
4
  var globalOptions = {
5
- storage: "localStorage",
6
- tokenKey: "access_token"
5
+ storage: "localStorage"
7
6
  };
8
7
  var configureTokenManager = (options) => {
9
8
  globalOptions = { ...globalOptions, ...options };
@@ -12,26 +11,42 @@ var TokenManager = class {
12
11
  constructor(options) {
13
12
  const opts = options || globalOptions;
14
13
  this.storage = opts.storage || "localStorage";
15
- this.tokenKey = opts.tokenKey || "access_token";
16
14
  }
17
- set(token) {
18
- if (this.storage === "localStorage") localStorage.setItem(this.tokenKey, token);
19
- else if (this.storage === "sessionStorage") sessionStorage.setItem(this.tokenKey, token);
20
- else document.cookie = `${this.tokenKey}=${token}; path=/`;
15
+ /** Set multiple tokens at once */
16
+ set(tokens) {
17
+ Object.entries(tokens).forEach(([key, value]) => {
18
+ if (this.storage === "localStorage") localStorage.setItem(key, value);
19
+ else if (this.storage === "sessionStorage") sessionStorage.setItem(key, value);
20
+ else document.cookie = `${key}=${value}; path=/`;
21
+ });
21
22
  }
22
- get() {
23
- if (this.storage === "localStorage") return localStorage.getItem(this.tokenKey);
24
- if (this.storage === "sessionStorage") return sessionStorage.getItem(this.tokenKey);
25
- const match = document.cookie.match(new RegExp("(^| )" + this.tokenKey + "=([^;]+)"));
26
- return match ? match[2] : null;
23
+ /** Get single token by key or all tokens in an array of keys */
24
+ get(keys) {
25
+ const keyArray = Array.isArray(keys) ? keys : [keys];
26
+ const result = {};
27
+ keyArray.forEach((key) => {
28
+ let value = null;
29
+ if (this.storage === "localStorage") value = localStorage.getItem(key);
30
+ else if (this.storage === "sessionStorage") value = sessionStorage.getItem(key);
31
+ else {
32
+ const match = document.cookie.match(new RegExp("(^| )" + key + "=([^;]+)"));
33
+ value = match ? match[2] : null;
34
+ }
35
+ result[key] = value;
36
+ });
37
+ return result;
27
38
  }
28
- remove() {
29
- if (this.storage === "localStorage") localStorage.removeItem(this.tokenKey);
30
- else if (this.storage === "sessionStorage") sessionStorage.removeItem(this.tokenKey);
31
- else document.cookie = `${this.tokenKey}=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
39
+ /** Remove multiple tokens by keys */
40
+ remove(keys) {
41
+ const keyArray = Array.isArray(keys) ? keys : [keys];
42
+ keyArray.forEach((key) => {
43
+ if (this.storage === "localStorage") localStorage.removeItem(key);
44
+ else if (this.storage === "sessionStorage") sessionStorage.removeItem(key);
45
+ else document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
46
+ });
32
47
  }
33
- decode() {
34
- const token = this.get();
48
+ /** Decode a single token by key */
49
+ decode(token) {
35
50
  if (!token) return null;
36
51
  try {
37
52
  return jwtDecode(token);
@@ -39,38 +54,29 @@ var TokenManager = class {
39
54
  return null;
40
55
  }
41
56
  }
42
- isExpired() {
43
- const decoded = this.decode();
57
+ /** Check if a token is expired */
58
+ isExpired(token) {
59
+ const decoded = this.decode(token);
44
60
  if (!decoded || !decoded.exp) return true;
45
61
  return Date.now() >= decoded.exp * 1e3;
46
62
  }
47
- getValid() {
48
- return this.isExpired() ? null : this.get();
49
- }
50
63
  };
51
64
 
52
65
  // src/hook.ts
53
- import { useEffect, useState } from "react";
54
- var useTokenManager = (options) => {
55
- const manager = new TokenManager(options);
56
- const [token, setTokenState] = useState(null);
57
- useEffect(() => {
58
- setTokenState(manager.getValid());
59
- }, []);
60
- const setToken = (value) => {
61
- manager.set(value);
62
- setTokenState(value);
63
- };
64
- const removeToken = () => {
65
- manager.remove();
66
- setTokenState(null);
67
- };
66
+ import { useMemo } from "react";
67
+ var useTokenManager = () => {
68
+ const manager = useMemo(() => new TokenManager(), []);
68
69
  return {
69
- token,
70
- setToken,
71
- removeToken,
72
- isExpired: () => manager.isExpired(),
73
- decode: () => manager.decode()
70
+ /** Set multiple tokens */
71
+ setTokens: (tokens) => manager.set(tokens),
72
+ /** Get multiple tokens by keys */
73
+ getTokens: (keys) => manager.get(keys),
74
+ /** Remove multiple tokens by keys */
75
+ removeTokens: (keys) => manager.remove(keys),
76
+ /** Decode a single token */
77
+ decodeToken: (token) => manager.decode(token),
78
+ /** Check expiration of a single token */
79
+ isExpired: (token) => manager.isExpired(token)
74
80
  };
75
81
  };
76
82
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-token-manager",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A simple React library to manage JWT tokens",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/core.ts CHANGED
@@ -1,75 +1,83 @@
1
1
  import type { JwtPayload } from 'jwt-decode'
2
2
  import * as jwtDecodeModule from 'jwt-decode'
3
3
 
4
- // Properly type the callable function
5
- const jwtDecode: <T = unknown>(token: string) => T =
4
+ const jwtDecode: <T = unknown>(token: string) => T =
6
5
  (jwtDecodeModule as any).default || jwtDecodeModule
7
6
 
8
-
9
7
  export type StorageType = 'localStorage' | 'sessionStorage' | 'cookie'
10
8
 
11
9
  export interface TokenManagerOptions {
12
10
  storage?: StorageType
13
- tokenKey?: string
14
11
  }
15
12
 
16
- // ---------------- Global configuration ----------------
17
13
  let globalOptions: TokenManagerOptions = {
18
14
  storage: 'localStorage',
19
- tokenKey: 'access_token',
20
15
  }
21
16
 
22
17
  export const configureTokenManager = (options: TokenManagerOptions) => {
23
18
  globalOptions = { ...globalOptions, ...options }
24
19
  }
25
20
 
26
- // ---------------- TokenManager Class ----------------
27
21
  export class TokenManager {
28
22
  private storage: StorageType
29
- private tokenKey: string
30
23
 
31
24
  constructor(options?: TokenManagerOptions) {
32
25
  const opts = options || globalOptions
33
26
  this.storage = opts.storage || 'localStorage'
34
- this.tokenKey = opts.tokenKey || 'access_token'
35
27
  }
36
28
 
37
- set(token: string) {
38
- if (this.storage === 'localStorage') localStorage.setItem(this.tokenKey, token)
39
- else if (this.storage === 'sessionStorage') sessionStorage.setItem(this.tokenKey, token)
40
- else document.cookie = `${this.tokenKey}=${token}; path=/`
29
+ /** Set multiple tokens at once */
30
+ set(tokens: Record<string, string>) {
31
+ Object.entries(tokens).forEach(([key, value]) => {
32
+ if (this.storage === 'localStorage') localStorage.setItem(key, value)
33
+ else if (this.storage === 'sessionStorage') sessionStorage.setItem(key, value)
34
+ else document.cookie = `${key}=${value}; path=/`
35
+ })
41
36
  }
42
37
 
43
- get(): string | null {
44
- if (this.storage === 'localStorage') return localStorage.getItem(this.tokenKey)
45
- if (this.storage === 'sessionStorage') return sessionStorage.getItem(this.tokenKey)
46
- const match = document.cookie.match(new RegExp('(^| )' + this.tokenKey + '=([^;]+)'))
47
- return match ? match[2] : null
38
+ /** Get single token by key or all tokens in an array of keys */
39
+ get(keys: string | string[]): Record<string, string | null> {
40
+ const keyArray = Array.isArray(keys) ? keys : [keys]
41
+ const result: Record<string, string | null> = {}
42
+
43
+ keyArray.forEach((key) => {
44
+ let value: string | null = null
45
+ if (this.storage === 'localStorage') value = localStorage.getItem(key)
46
+ else if (this.storage === 'sessionStorage') value = sessionStorage.getItem(key)
47
+ else {
48
+ const match = document.cookie.match(new RegExp('(^| )' + key + '=([^;]+)'))
49
+ value = match ? match[2] : null
50
+ }
51
+ result[key] = value
52
+ })
53
+
54
+ return result
48
55
  }
49
56
 
50
- remove() {
51
- if (this.storage === 'localStorage') localStorage.removeItem(this.tokenKey)
52
- else if (this.storage === 'sessionStorage') sessionStorage.removeItem(this.tokenKey)
53
- else document.cookie = `${this.tokenKey}=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`
57
+ /** Remove multiple tokens by keys */
58
+ remove(keys: string | string[]) {
59
+ const keyArray = Array.isArray(keys) ? keys : [keys]
60
+ keyArray.forEach((key) => {
61
+ if (this.storage === 'localStorage') localStorage.removeItem(key)
62
+ else if (this.storage === 'sessionStorage') sessionStorage.removeItem(key)
63
+ else document.cookie = `${key}=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`
64
+ })
54
65
  }
55
66
 
56
- decode<T = unknown>(): T | null {
57
- const token = this.get()
67
+ /** Decode a single token by key */
68
+ decode<T = unknown>(token: string): T | null {
58
69
  if (!token) return null
59
70
  try {
60
- return jwtDecode<T>(token) // Now callable
71
+ return jwtDecode<T>(token)
61
72
  } catch {
62
73
  return null
63
74
  }
64
75
  }
65
76
 
66
- isExpired(): boolean {
67
- const decoded = this.decode<JwtPayload>()
77
+ /** Check if a token is expired */
78
+ isExpired(token: string): boolean {
79
+ const decoded = this.decode<JwtPayload>(token)
68
80
  if (!decoded || !decoded.exp) return true
69
81
  return Date.now() >= decoded.exp * 1000
70
82
  }
71
-
72
- getValid(): string | null {
73
- return this.isExpired() ? null : this.get()
74
- }
75
83
  }
package/src/hook.ts CHANGED
@@ -1,40 +1,23 @@
1
- import { useEffect, useState } from 'react'
2
- import { TokenManager, TokenManagerOptions } from './core'
1
+ import { useMemo } from 'react'
2
+ import { TokenManager } from './core'
3
3
 
4
- export interface UseTokenManagerReturn {
5
- token: string | null
6
- setToken: (value: string) => void
7
- removeToken: () => void
8
- isExpired: () => boolean
9
- decode: <T = unknown>() => T | null
10
- }
11
-
12
- export const useTokenManager = (
13
- options?: TokenManagerOptions
14
- ): UseTokenManagerReturn => {
15
- const manager = new TokenManager(options)
4
+ export const useTokenManager = () => {
5
+ const manager = useMemo(() => new TokenManager(), [])
16
6
 
17
- const [token, setTokenState] = useState<string | null>(null)
7
+ return {
8
+ /** Set multiple tokens */
9
+ setTokens: (tokens: Record<string, string>) => manager.set(tokens),
18
10
 
19
- useEffect(() => {
20
- setTokenState(manager.getValid())
21
- }, [])
11
+ /** Get multiple tokens by keys */
12
+ getTokens: (keys: string | string[]) => manager.get(keys),
22
13
 
23
- const setToken = (value: string) => {
24
- manager.set(value)
25
- setTokenState(value)
26
- }
14
+ /** Remove multiple tokens by keys */
15
+ removeTokens: (keys: string | string[]) => manager.remove(keys),
27
16
 
28
- const removeToken = () => {
29
- manager.remove()
30
- setTokenState(null)
31
- }
17
+ /** Decode a single token */
18
+ decodeToken: <T = unknown>(token: string) => manager.decode<T>(token),
32
19
 
33
- return {
34
- token,
35
- setToken,
36
- removeToken,
37
- isExpired: () => manager.isExpired(),
38
- decode: <T = unknown>() => manager.decode<T>(),
20
+ /** Check expiration of a single token */
21
+ isExpired: (token: string) => manager.isExpired(token),
39
22
  }
40
23
  }
@@ -1,38 +0,0 @@
1
- import { useEffect, useState, useMemo } from 'react'
2
- import { TokenManager } from './core'
3
-
4
- export interface UseTokenManagerReturn {
5
- token: string | null
6
- setToken: (value: string) => void
7
- removeToken: () => void
8
- isExpired: () => boolean
9
- decode: <T = unknown>() => T | null
10
- }
11
-
12
- export const useTokenManager = (): UseTokenManagerReturn => {
13
- const manager = useMemo(() => new TokenManager(), [])
14
-
15
- const [token, setTokenState] = useState<string | null>(null)
16
-
17
- useEffect(() => {
18
- setTokenState(manager.getValid())
19
- }, [manager])
20
-
21
- const setToken = (value: string) => {
22
- manager.set(value)
23
- setTokenState(value)
24
- }
25
-
26
- const removeToken = () => {
27
- manager.remove()
28
- setTokenState(null)
29
- }
30
-
31
- return {
32
- token,
33
- setToken,
34
- removeToken,
35
- isExpired: () => manager.isExpired(),
36
- decode: <T = unknown>() => manager.decode<T>(),
37
- }
38
- }