axauth 2.0.0 → 2.1.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.
@@ -1,5 +1,11 @@
1
1
  /**
2
- * Token and credential expiry check utilities.
2
+ * Token and credential expiry/refresh utilities.
3
+ *
4
+ * Provides field detection for common OAuth credential formats:
5
+ * - Google OAuth: expiry_date (ms), refresh_token
6
+ * - Generic OAuth: expires_at (s or ms), refresh_token
7
+ * - OpenCode: expires (ms), refresh
8
+ * - Claude: expiresAt (ms), refreshToken (camelCase)
3
9
  */
4
10
  /**
5
11
  * Check if a JWT token is expired.
@@ -23,4 +29,48 @@ declare function isTokenExpired(token: string, bufferSeconds?: number): boolean
23
29
  * @returns true if expired, false if valid, undefined if no expiry field found
24
30
  */
25
31
  declare function isCredentialExpired(data: Record<string, unknown>, bufferSeconds?: number): boolean | undefined;
26
- export { isCredentialExpired, isTokenExpired };
32
+ /**
33
+ * Extract expiry timestamp in milliseconds from credential data.
34
+ *
35
+ * Checks common expiry field names in order of preference:
36
+ * - `expiry_date`: Google OAuth (milliseconds)
37
+ * - `expires_at`: Generic OAuth (seconds or milliseconds, auto-detected)
38
+ * - `expiresAt`: Claude (seconds or milliseconds, auto-detected)
39
+ * - `expires`: OpenCode (seconds or milliseconds, auto-detected)
40
+ */
41
+ declare function extractExpiryTimestamp(data: Record<string, unknown>): number | undefined;
42
+ /**
43
+ * Extract expiry date from credential data.
44
+ *
45
+ * Convenience wrapper around {@link extractExpiryTimestamp} that returns
46
+ * a Date object instead of milliseconds.
47
+ *
48
+ * @param data - The credential data object
49
+ * @returns Date if expiry field found, undefined otherwise
50
+ */
51
+ declare function extractExpiryDate(data: Record<string, unknown>): Date | undefined;
52
+ /**
53
+ * Credential data containing a refresh token.
54
+ *
55
+ * Union of all supported refresh token field naming conventions.
56
+ */
57
+ type RefreshableCredentials = (Record<string, unknown> & {
58
+ refresh_token: string;
59
+ }) | (Record<string, unknown> & {
60
+ refreshToken: string;
61
+ }) | (Record<string, unknown> & {
62
+ refresh: string;
63
+ });
64
+ /**
65
+ * Check if credential data contains a refresh token.
66
+ *
67
+ * Supports multiple field naming conventions:
68
+ * - `refresh_token`: Standard OAuth / Google / Generic
69
+ * - `refreshToken`: Claude (camelCase)
70
+ * - `refresh`: OpenCode
71
+ *
72
+ * @param data - The credential data object (accepts unknown for safety)
73
+ * @returns true if a refresh token field exists with a string value
74
+ */
75
+ declare function isRefreshable(data: unknown): data is RefreshableCredentials;
76
+ export { extractExpiryDate, extractExpiryTimestamp, isCredentialExpired, isRefreshable, isTokenExpired, type RefreshableCredentials, };
@@ -1,5 +1,11 @@
1
1
  /**
2
- * Token and credential expiry check utilities.
2
+ * Token and credential expiry/refresh utilities.
3
+ *
4
+ * Provides field detection for common OAuth credential formats:
5
+ * - Google OAuth: expiry_date (ms), refresh_token
6
+ * - Generic OAuth: expires_at (s or ms), refresh_token
7
+ * - OpenCode: expires (ms), refresh
8
+ * - Claude: expiresAt (ms), refreshToken (camelCase)
3
9
  */
4
10
  /**
5
11
  * Timestamp threshold to distinguish seconds from milliseconds.
@@ -65,7 +71,15 @@ function isCredentialExpired(data, bufferSeconds = 60) {
65
71
  const bufferMs = bufferSeconds * 1000;
66
72
  return nowMs > expiryTimestampMs - bufferMs;
67
73
  }
68
- /** Extract expiry timestamp in milliseconds from credential data. */
74
+ /**
75
+ * Extract expiry timestamp in milliseconds from credential data.
76
+ *
77
+ * Checks common expiry field names in order of preference:
78
+ * - `expiry_date`: Google OAuth (milliseconds)
79
+ * - `expires_at`: Generic OAuth (seconds or milliseconds, auto-detected)
80
+ * - `expiresAt`: Claude (seconds or milliseconds, auto-detected)
81
+ * - `expires`: OpenCode (seconds or milliseconds, auto-detected)
82
+ */
69
83
  function extractExpiryTimestamp(data) {
70
84
  // Google OAuth uses expiry_date (milliseconds)
71
85
  if (typeof data.expiry_date === "number") {
@@ -77,10 +91,62 @@ function extractExpiryTimestamp(data) {
77
91
  ? data.expires_at * 1000
78
92
  : data.expires_at;
79
93
  }
80
- // OpenCode uses expires (milliseconds)
94
+ // Claude uses expiresAt (milliseconds, camelCase)
95
+ if (typeof data.expiresAt === "number") {
96
+ return data.expiresAt < SECONDS_THRESHOLD
97
+ ? data.expiresAt * 1000
98
+ : data.expiresAt;
99
+ }
100
+ // OpenCode uses expires (milliseconds, but apply heuristic for safety)
81
101
  if (typeof data.expires === "number") {
82
- return data.expires;
102
+ return data.expires < SECONDS_THRESHOLD
103
+ ? data.expires * 1000
104
+ : data.expires;
83
105
  }
84
106
  return undefined;
85
107
  }
86
- export { isCredentialExpired, isTokenExpired };
108
+ /**
109
+ * Extract expiry date from credential data.
110
+ *
111
+ * Convenience wrapper around {@link extractExpiryTimestamp} that returns
112
+ * a Date object instead of milliseconds.
113
+ *
114
+ * @param data - The credential data object
115
+ * @returns Date if expiry field found, undefined otherwise
116
+ */
117
+ function extractExpiryDate(data) {
118
+ const ts = extractExpiryTimestamp(data);
119
+ if (ts === undefined)
120
+ return undefined;
121
+ return new Date(ts);
122
+ }
123
+ /**
124
+ * Check if credential data contains a refresh token.
125
+ *
126
+ * Supports multiple field naming conventions:
127
+ * - `refresh_token`: Standard OAuth / Google / Generic
128
+ * - `refreshToken`: Claude (camelCase)
129
+ * - `refresh`: OpenCode
130
+ *
131
+ * @param data - The credential data object (accepts unknown for safety)
132
+ * @returns true if a refresh token field exists with a string value
133
+ */
134
+ function isRefreshable(data) {
135
+ if (typeof data !== "object" || data === null)
136
+ return false;
137
+ const record = data;
138
+ // Standard OAuth field name
139
+ if ("refresh_token" in record && typeof record.refresh_token === "string") {
140
+ return true;
141
+ }
142
+ // Claude uses camelCase
143
+ if ("refreshToken" in record && typeof record.refreshToken === "string") {
144
+ return true;
145
+ }
146
+ // OpenCode uses 'refresh'
147
+ if ("refresh" in record && typeof record.refresh === "string") {
148
+ return true;
149
+ }
150
+ return false;
151
+ }
152
+ export { extractExpiryDate, extractExpiryTimestamp, isCredentialExpired, isRefreshable, isTokenExpired, };
package/dist/index.d.ts CHANGED
@@ -37,5 +37,5 @@ export type { AuthStatus, Credentials } from "./auth/types.js";
37
37
  export { checkAllAuth, checkAuth, credentialsToEnvironment, extractRawCredentials, extractRawCredentialsFromDirectory, getAccessToken, getAgentAccessToken, getCredentialsEnvironmentVariableName, installCredentials, installCredentialsFromEnvironmentVariable, removeCredentials, getAdapter, getAllAdapters, getCapabilities, type ExtractOptions, type InstallFromEnvironmentOptions, } from "./auth/registry.js";
38
38
  export { getVaultConfig, isVaultConfigured, type VaultConfig, } from "./vault/vault-config.js";
39
39
  export { fetchVaultCredentials, type VaultFailureReason, type VaultFetchOptions, type VaultResult, } from "./vault/vault-client.js";
40
- export { isCredentialExpired, isTokenExpired, } from "./auth/is-token-expired.js";
40
+ export { extractExpiryDate, extractExpiryTimestamp, isCredentialExpired, isRefreshable, isTokenExpired, type RefreshableCredentials, } from "./auth/is-token-expired.js";
41
41
  export { refreshAndPersist, refreshCredentials, type RefreshAndPersistResult, type RefreshOptions, type RefreshResult, } from "./auth/refresh-credentials.js";
package/dist/index.js CHANGED
@@ -40,6 +40,6 @@ getAdapter, getAllAdapters, getCapabilities, } from "./auth/registry.js";
40
40
  // Vault utilities
41
41
  export { getVaultConfig, isVaultConfigured, } from "./vault/vault-config.js";
42
42
  export { fetchVaultCredentials, } from "./vault/vault-client.js";
43
- // Token refresh utilities
44
- export { isCredentialExpired, isTokenExpired, } from "./auth/is-token-expired.js";
43
+ // Token/credential utilities
44
+ export { extractExpiryDate, extractExpiryTimestamp, isCredentialExpired, isRefreshable, isTokenExpired, } from "./auth/is-token-expired.js";
45
45
  export { refreshAndPersist, refreshCredentials, } from "./auth/refresh-credentials.js";
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "axauth",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "2.0.0",
5
+ "version": "2.1.0",
6
6
  "description": "Authentication management library and CLI for AI coding agents",
7
7
  "repository": {
8
8
  "type": "git",
@@ -68,25 +68,25 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@commander-js/extra-typings": "^14.0.0",
71
- "@inquirer/password": "^5.0.3",
71
+ "@inquirer/password": "^5.0.4",
72
72
  "axconfig": "^3.6.0",
73
- "axexec": "^1.1.0",
73
+ "axexec": "^1.1.6",
74
74
  "axshared": "^2.0.0",
75
75
  "commander": "^14.0.2",
76
76
  "zod": "^4.3.5"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@total-typescript/ts-reset": "^0.6.1",
80
- "@types/node": "^25.0.5",
81
- "@vitest/coverage-v8": "^4.0.16",
80
+ "@types/node": "^25.0.9",
81
+ "@vitest/coverage-v8": "^4.0.17",
82
82
  "eslint": "^9.39.2",
83
83
  "eslint-config-axkit": "^1.0.0",
84
84
  "fta-check": "^1.5.1",
85
85
  "fta-cli": "^3.0.0",
86
- "knip": "^5.80.2",
86
+ "knip": "^5.81.0",
87
87
  "prettier": "3.7.4",
88
88
  "semantic-release": "^25.0.2",
89
89
  "typescript": "^5.9.3",
90
- "vitest": "^4.0.16"
90
+ "vitest": "^4.0.17"
91
91
  }
92
92
  }