@cortexkit/anthropic-auth-core 1.1.2 → 1.1.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/dist/accounts.d.ts +8 -0
- package/dist/accounts.js +49 -3
- package/package.json +1 -1
package/dist/accounts.d.ts
CHANGED
|
@@ -89,6 +89,14 @@ export type AccountRefreshError = {
|
|
|
89
89
|
export declare function getAccountStoragePath(): string;
|
|
90
90
|
export declare function loadAccounts(path?: string): Promise<AccountStorage | null>;
|
|
91
91
|
export declare function saveAccounts(storage: AccountStorage, path?: string): Promise<void>;
|
|
92
|
+
export declare function acquireRefreshFileLock(options: {
|
|
93
|
+
name: string;
|
|
94
|
+
ttlMs: number;
|
|
95
|
+
path?: string;
|
|
96
|
+
now?: () => number;
|
|
97
|
+
}): Promise<{
|
|
98
|
+
release: () => Promise<void>;
|
|
99
|
+
} | null>;
|
|
92
100
|
export declare function isCache1hPersistentlyEnabled(storage: AccountStorage | null): boolean;
|
|
93
101
|
export declare function getCache1hPersistentMode(storage: AccountStorage | null): Cache1hMode;
|
|
94
102
|
export declare function setCache1hPersistentEnabled(enabled: boolean, mode?: Cache1hMode, path?: string): Promise<AccountStorage>;
|
package/dist/accounts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
-
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import { ClaudeOAuthRefreshError, refreshClaudeOAuthToken } from "./auth.js";
|
|
@@ -8,7 +8,8 @@ import { log } from "./logger.js";
|
|
|
8
8
|
export const ACCOUNT_FILE_NAME = 'anthropic-auth.json';
|
|
9
9
|
export const QUOTA_URL = 'https://api.anthropic.com/api/oauth/usage';
|
|
10
10
|
const DEFAULT_FALLBACK_ON = [401, 403, 429];
|
|
11
|
-
const
|
|
11
|
+
const MIN_REFRESH_BEFORE_EXPIRY_MINUTES = 240;
|
|
12
|
+
const DEFAULT_REFRESH_BEFORE_EXPIRY_MINUTES = MIN_REFRESH_BEFORE_EXPIRY_MINUTES;
|
|
12
13
|
const DEFAULT_REFRESH_INTERVAL_MINUTES = 10;
|
|
13
14
|
const MIN_REFRESH_RETRY_DELAY_MS = 5 * 60_000;
|
|
14
15
|
const MAX_REFRESH_RETRY_DELAY_MS = 60 * 60_000;
|
|
@@ -159,6 +160,51 @@ export async function saveAccounts(storage, path = getAccountStoragePath()) {
|
|
|
159
160
|
});
|
|
160
161
|
await rename(tempPath, path);
|
|
161
162
|
}
|
|
163
|
+
export async function acquireRefreshFileLock(options) {
|
|
164
|
+
const accountPath = options.path ?? getAccountStoragePath();
|
|
165
|
+
const lockDir = `${accountPath}.${options.name}.lock`;
|
|
166
|
+
const ownerPath = join(lockDir, 'owner.json');
|
|
167
|
+
const ownerId = randomUUID();
|
|
168
|
+
const now = options.now ?? Date.now;
|
|
169
|
+
async function tryAcquire() {
|
|
170
|
+
try {
|
|
171
|
+
await mkdir(lockDir, { mode: 0o700 });
|
|
172
|
+
await writeFile(ownerPath, `${JSON.stringify({ ownerId, expiresAt: now() + options.ttlMs })}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
if (error.code !== 'EEXIST')
|
|
177
|
+
throw error;
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (!(await tryAcquire())) {
|
|
182
|
+
try {
|
|
183
|
+
const owner = JSON.parse(await readFile(ownerPath, 'utf8'));
|
|
184
|
+
if (Number(owner?.expiresAt) > now())
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Broken owner metadata is treated as stale.
|
|
189
|
+
}
|
|
190
|
+
await rm(lockDir, { recursive: true, force: true }).catch(() => { });
|
|
191
|
+
if (!(await tryAcquire()))
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
release: async () => {
|
|
196
|
+
try {
|
|
197
|
+
const owner = JSON.parse(await readFile(ownerPath, 'utf8'));
|
|
198
|
+
if (owner?.ownerId !== ownerId)
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
await rm(lockDir, { recursive: true, force: true }).catch(() => { });
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
}
|
|
162
208
|
export function isCache1hPersistentlyEnabled(storage) {
|
|
163
209
|
return storage?.claudeCache?.enabled === true;
|
|
164
210
|
}
|
|
@@ -284,7 +330,7 @@ function refreshEnabled(storage) {
|
|
|
284
330
|
function refreshBeforeExpiryMs(storage) {
|
|
285
331
|
const minutes = storage?.refresh?.refreshBeforeExpiryMinutes ??
|
|
286
332
|
DEFAULT_REFRESH_BEFORE_EXPIRY_MINUTES;
|
|
287
|
-
return Math.max(
|
|
333
|
+
return Math.max(MIN_REFRESH_BEFORE_EXPIRY_MINUTES, minutes) * 60_000;
|
|
288
334
|
}
|
|
289
335
|
export function getRefreshIntervalMs(storage) {
|
|
290
336
|
const minutes = storage?.refresh?.intervalMinutes ?? DEFAULT_REFRESH_INTERVAL_MINUTES;
|