@open-vibe-lab/open-sub-auth 0.1.0 → 0.1.1
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/cli/{claude-3WKImhqM.mjs → claude-Bu4Vb3Sa.mjs} +18 -4
- package/dist/cli/{claude-3WKImhqM.mjs.map → claude-Bu4Vb3Sa.mjs.map} +1 -1
- package/dist/cli/{registry-Cp-_Ipc6.mjs → errors-BQeS4Q64.mjs} +11 -37
- package/dist/cli/errors-BQeS4Q64.mjs.map +1 -0
- package/dist/cli/export-CpcD-XlM.mjs +11 -0
- package/dist/cli/export-CpcD-XlM.mjs.map +1 -0
- package/dist/cli/import-BZDRd0Nj.mjs +40 -0
- package/dist/cli/import-BZDRd0Nj.mjs.map +1 -0
- package/dist/cli/index.mjs +61 -12
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/{login-_HdTW5J_.mjs → login-DfG9kqBN.mjs} +7 -6
- package/dist/cli/login-DfG9kqBN.mjs.map +1 -0
- package/dist/cli/{logout-CZm-tSVH.mjs → logout-BdnhQ3aw.mjs} +7 -6
- package/dist/cli/logout-BdnhQ3aw.mjs.map +1 -0
- package/dist/cli/manager-C-RjavF0.mjs +129 -0
- package/dist/cli/manager-C-RjavF0.mjs.map +1 -0
- package/dist/cli/{oauth-pkce-Bi02-h23.mjs → oauth-pkce-CCKyG5wP.mjs} +4 -10
- package/dist/cli/{oauth-pkce-Bi02-h23.mjs.map → oauth-pkce-CCKyG5wP.mjs.map} +1 -1
- package/dist/cli/{openai-codex-DJi_Q6Zm.mjs → openai-codex-CKKY1Gu_.mjs} +3 -3
- package/dist/cli/{openai-codex-DJi_Q6Zm.mjs.map → openai-codex-CKKY1Gu_.mjs.map} +1 -1
- package/dist/cli/registry-Dv4TWuqv.mjs +39 -0
- package/dist/cli/registry-Dv4TWuqv.mjs.map +1 -0
- package/dist/cli/{status-C-vkcjVM.mjs → status-CvktIWmx.mjs} +6 -5
- package/dist/cli/status-CvktIWmx.mjs.map +1 -0
- package/dist/cli/{manager-CKGbp7Yz.mjs → store-57VEqlSz.mjs} +16 -132
- package/dist/cli/store-57VEqlSz.mjs.map +1 -0
- package/dist/cli/{token-DF_-h4Rb.mjs → token-Ce_FmqGM.mjs} +7 -6
- package/dist/cli/token-Ce_FmqGM.mjs.map +1 -0
- package/dist/index.cjs +271 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -4
- package/dist/index.d.mts +67 -4
- package/dist/index.mjs +265 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/dist/cli/login-_HdTW5J_.mjs.map +0 -1
- package/dist/cli/logout-CZm-tSVH.mjs.map +0 -1
- package/dist/cli/manager-CKGbp7Yz.mjs.map +0 -1
- package/dist/cli/registry-Cp-_Ipc6.mjs.map +0 -1
- package/dist/cli/status-C-vkcjVM.mjs.map +0 -1
- package/dist/cli/token-DF_-h4Rb.mjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { r as registerProvider } from "./registry-
|
|
3
|
-
import { n as refreshAccessToken, t as executePKCEFlow } from "./oauth-pkce-
|
|
2
|
+
import { r as registerProvider } from "./registry-Dv4TWuqv.mjs";
|
|
3
|
+
import { n as refreshAccessToken, t as executePKCEFlow } from "./oauth-pkce-CCKyG5wP.mjs";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
//#region src/providers/claude.ts
|
|
6
6
|
const CLAUDE_CONFIG = {
|
|
@@ -49,8 +49,22 @@ var ClaudeProvider = class {
|
|
|
49
49
|
}
|
|
50
50
|
getAccountLabel(_tokenSet) {}
|
|
51
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Import a Claude OAuth token from the CLAUDE_CODE_OAUTH_TOKEN environment variable.
|
|
54
|
+
* This token is used directly as the access token for API calls.
|
|
55
|
+
*/
|
|
56
|
+
function importClaudeTokenFromEnv() {
|
|
57
|
+
const token = process.env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
58
|
+
if (!token) return null;
|
|
59
|
+
return {
|
|
60
|
+
accessToken: token,
|
|
61
|
+
refreshToken: null,
|
|
62
|
+
expiresAt: Date.now() + 36e5,
|
|
63
|
+
tokenType: "bearer"
|
|
64
|
+
};
|
|
65
|
+
}
|
|
52
66
|
registerProvider("claude", () => new ClaudeProvider());
|
|
53
67
|
//#endregion
|
|
54
|
-
export { ClaudeProvider };
|
|
68
|
+
export { ClaudeProvider, importClaudeTokenFromEnv };
|
|
55
69
|
|
|
56
|
-
//# sourceMappingURL=claude-
|
|
70
|
+
//# sourceMappingURL=claude-Bu4Vb3Sa.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-
|
|
1
|
+
{"version":3,"file":"claude-Bu4Vb3Sa.mjs","names":[],"sources":["../../src/providers/claude.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { executePKCEFlow, refreshAccessToken } from \"@/core/oauth-pkce.ts\";\nimport type { AuthHeaders, LoginOptions, Provider, ProviderConfig, TokenSet } from \"@/types.ts\";\nimport { registerProvider } from \"@/providers/registry.ts\";\n\nconst CLAUDE_CONFIG: ProviderConfig = {\n name: \"claude\",\n displayName: \"Claude Pro/Max\",\n authorizationEndpoint: \"https://claude.ai/oauth/authorize\",\n tokenEndpoint: \"https://console.anthropic.com/v1/oauth/token\",\n clientId: \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\",\n scopes: [\"org:create_api_key\", \"user:profile\", \"user:inference\"],\n grantType: \"authorization_code\",\n // Claude only supports console.anthropic.com redirect URI (no localhost),\n // and its token endpoint requires JSON body with state field\n tokenBodyFormat: \"json\",\n stateIsVerifier: true,\n};\n\n/** Redirect URI used in manual/headless mode (user copies code from browser) */\nconst MANUAL_REDIRECT_URI = \"https://console.anthropic.com/oauth/code/callback\";\n\nexport class ClaudeProvider implements Provider {\n readonly config = CLAUDE_CONFIG;\n\n async login(options?: LoginOptions): Promise<TokenSet> {\n // Claude only allows console.anthropic.com/oauth/code/callback as redirect URI.\n // Local callback server is not supported, so always use manual (code-paste) mode.\n return executePKCEFlow({\n config: this.config,\n loginOptions: { ...options, manual: true },\n manualRedirectUri: MANUAL_REDIRECT_URI,\n });\n }\n\n async refresh(refreshToken: string): Promise<TokenSet> {\n return refreshAccessToken(this.config, refreshToken);\n }\n\n getAuthHeaders(accessToken: string): AuthHeaders {\n return {\n authorization: `Bearer ${accessToken}`,\n \"anthropic-version\": \"2023-06-01\",\n \"anthropic-beta\": \"oauth-2025-04-20\",\n \"content-type\": \"application/json\",\n };\n }\n\n getAccountId(tokenSet: TokenSet): string {\n // Claude doesn't provide a profile endpoint, so derive ID from refresh token hash\n const source = tokenSet.refreshToken ?? tokenSet.accessToken;\n return createHash(\"sha256\").update(source).digest(\"hex\").slice(0, 16);\n }\n\n getAccountLabel(_tokenSet: TokenSet): string | undefined {\n // Claude tokens don't carry user identity info\n return undefined;\n }\n}\n\n/**\n * Import a Claude OAuth token from the CLAUDE_CODE_OAUTH_TOKEN environment variable.\n * This token is used directly as the access token for API calls.\n */\nexport function importClaudeTokenFromEnv(): TokenSet | null {\n const token = process.env.CLAUDE_CODE_OAUTH_TOKEN;\n if (!token) return null;\n return {\n accessToken: token,\n refreshToken: null,\n expiresAt: Date.now() + 3600_000, // Assume 1 hour; will refresh as needed\n tokenType: \"bearer\",\n };\n}\n\n// Auto-register\nregisterProvider(\"claude\", () => new ClaudeProvider());\n"],"mappings":";;;;;AAKA,MAAM,gBAAgC;CACpC,MAAM;CACN,aAAa;CACb,uBAAuB;CACvB,eAAe;CACf,UAAU;CACV,QAAQ;EAAC;EAAsB;EAAgB;EAAiB;CAChE,WAAW;CAGX,iBAAiB;CACjB,iBAAiB;CAClB;;AAGD,MAAM,sBAAsB;AAE5B,IAAa,iBAAb,MAAgD;CAC9C,SAAkB;CAElB,MAAM,MAAM,SAA2C;AAGrD,SAAO,gBAAgB;GACrB,QAAQ,KAAK;GACb,cAAc;IAAE,GAAG;IAAS,QAAQ;IAAM;GAC1C,mBAAmB;GACpB,CAAC;;CAGJ,MAAM,QAAQ,cAAyC;AACrD,SAAO,mBAAmB,KAAK,QAAQ,aAAa;;CAGtD,eAAe,aAAkC;AAC/C,SAAO;GACL,eAAe,UAAU;GACzB,qBAAqB;GACrB,kBAAkB;GAClB,gBAAgB;GACjB;;CAGH,aAAa,UAA4B;EAEvC,MAAM,SAAS,SAAS,gBAAgB,SAAS;AACjD,SAAO,WAAW,SAAS,CAAC,OAAO,OAAO,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;CAGvE,gBAAgB,WAAyC;;;;;;AAU3D,SAAgB,2BAA4C;CAC1D,MAAM,QAAQ,QAAQ,IAAI;AAC1B,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EACL,aAAa;EACb,cAAc;EACd,WAAW,KAAK,KAAK,GAAG;EACxB,WAAW;EACZ;;AAIH,iBAAiB,gBAAgB,IAAI,gBAAgB,CAAC"}
|
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//#region \0rolldown/runtime.js
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __exportAll = (all, no_symbols) => {
|
|
5
|
-
let target = {};
|
|
6
|
-
for (var name in all) __defProp(target, name, {
|
|
7
|
-
get: all[name],
|
|
8
|
-
enumerable: true
|
|
9
|
-
});
|
|
10
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
11
|
-
return target;
|
|
12
|
-
};
|
|
13
|
-
//#endregion
|
|
14
2
|
//#region src/errors.ts
|
|
15
3
|
var OpenSubAuthError = class extends Error {
|
|
16
4
|
constructor(message) {
|
|
@@ -18,6 +6,13 @@ var OpenSubAuthError = class extends Error {
|
|
|
18
6
|
this.name = "OpenSubAuthError";
|
|
19
7
|
}
|
|
20
8
|
};
|
|
9
|
+
var AuthenticationError = class extends OpenSubAuthError {
|
|
10
|
+
constructor(message, provider) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.provider = provider;
|
|
13
|
+
this.name = "AuthenticationError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
21
16
|
var TokenExpiredError = class extends OpenSubAuthError {
|
|
22
17
|
constructor(provider) {
|
|
23
18
|
super(`Access token for "${provider}" has expired and no refresh token is available. Please login again.`);
|
|
@@ -27,7 +22,8 @@ var TokenExpiredError = class extends OpenSubAuthError {
|
|
|
27
22
|
};
|
|
28
23
|
var TokenRefreshError = class extends OpenSubAuthError {
|
|
29
24
|
constructor(provider, cause_) {
|
|
30
|
-
|
|
25
|
+
const causeType = cause_ instanceof Error ? cause_.constructor.name : typeof cause_;
|
|
26
|
+
super(`Failed to refresh token for "${provider}" (${causeType}). Check logs for details.`);
|
|
31
27
|
this.provider = provider;
|
|
32
28
|
this.cause_ = cause_;
|
|
33
29
|
this.name = "TokenRefreshError";
|
|
@@ -69,28 +65,6 @@ var StateMismatchError = class extends OpenSubAuthError {
|
|
|
69
65
|
}
|
|
70
66
|
};
|
|
71
67
|
//#endregion
|
|
72
|
-
|
|
73
|
-
var registry_exports = /* @__PURE__ */ __exportAll({
|
|
74
|
-
getProvider: () => getProvider,
|
|
75
|
-
listProviders: () => listProviders,
|
|
76
|
-
registerProvider: () => registerProvider
|
|
77
|
-
});
|
|
78
|
-
const providers = /* @__PURE__ */ new Map();
|
|
79
|
-
/** Register a provider factory */
|
|
80
|
-
function registerProvider(name, factory) {
|
|
81
|
-
providers.set(name, factory);
|
|
82
|
-
}
|
|
83
|
-
/** Get a provider instance by name */
|
|
84
|
-
function getProvider(name) {
|
|
85
|
-
const factory = providers.get(name);
|
|
86
|
-
if (!factory) throw new ProviderNotFoundError(name);
|
|
87
|
-
return factory();
|
|
88
|
-
}
|
|
89
|
-
/** List all registered provider names */
|
|
90
|
-
function listProviders() {
|
|
91
|
-
return Array.from(providers.keys());
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
|
-
export { NoCredentialError as a, StateMismatchError as c, registry_exports as i, TokenExpiredError as l, listProviders as n, OAuthCallbackError as o, registerProvider as r, OAuthTimeoutError as s, getProvider as t, TokenRefreshError as u };
|
|
68
|
+
export { ProviderNotFoundError as a, TokenRefreshError as c, OAuthTimeoutError as i, NoCredentialError as n, StateMismatchError as o, OAuthCallbackError as r, TokenExpiredError as s, AuthenticationError as t };
|
|
95
69
|
|
|
96
|
-
//# sourceMappingURL=
|
|
70
|
+
//# sourceMappingURL=errors-BQeS4Q64.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-BQeS4Q64.mjs","names":[],"sources":["../../src/errors.ts"],"sourcesContent":["export class OpenSubAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenSubAuthError\";\n }\n}\n\nexport class AuthenticationError extends OpenSubAuthError {\n constructor(\n message: string,\n public readonly provider?: string,\n ) {\n super(message);\n this.name = \"AuthenticationError\";\n }\n}\n\nexport class TokenExpiredError extends OpenSubAuthError {\n constructor(public readonly provider: string) {\n super(\n `Access token for \"${provider}\" has expired and no refresh token is available. Please login again.`,\n );\n this.name = \"TokenExpiredError\";\n }\n}\n\nexport class TokenRefreshError extends OpenSubAuthError {\n constructor(\n public readonly provider: string,\n public readonly cause_: unknown,\n ) {\n // Use only the error class name, not .message — cause may contain token values\n // from upstream HTTP responses that should not be propagated to callers.\n const causeType = cause_ instanceof Error ? cause_.constructor.name : typeof cause_;\n super(`Failed to refresh token for \"${provider}\" (${causeType}). Check logs for details.`);\n this.name = \"TokenRefreshError\";\n }\n}\n\nexport class ProviderNotFoundError extends OpenSubAuthError {\n constructor(public readonly providerName: string) {\n super(\n `Provider \"${providerName}\" is not registered. Available providers can be listed with listProviders().`,\n );\n this.name = \"ProviderNotFoundError\";\n }\n}\n\nexport class NoCredentialError extends OpenSubAuthError {\n constructor(\n public readonly provider: string,\n public readonly accountId?: string,\n ) {\n const msg = accountId\n ? `No stored credential for \"${provider}\" account \"${accountId}\". Please login first.`\n : `No stored credential for \"${provider}\". Please login first.`;\n super(msg);\n this.name = \"NoCredentialError\";\n }\n}\n\nexport class OAuthCallbackError extends OpenSubAuthError {\n constructor(message: string) {\n super(message);\n this.name = \"OAuthCallbackError\";\n }\n}\n\nexport class OAuthTimeoutError extends OpenSubAuthError {\n constructor(public readonly timeoutMs: number) {\n super(`OAuth login timed out after ${Math.round(timeoutMs / 1000)} seconds. Please try again.`);\n this.name = \"OAuthTimeoutError\";\n }\n}\n\nexport class StateMismatchError extends OpenSubAuthError {\n constructor() {\n super(\"OAuth state parameter mismatch — possible CSRF attack. Please try again.\");\n this.name = \"StateMismatchError\";\n }\n}\n"],"mappings":";;AAAA,IAAa,mBAAb,cAAsC,MAAM;CAC1C,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAIhB,IAAa,sBAAb,cAAyC,iBAAiB;CACxD,YACE,SACA,UACA;AACA,QAAM,QAAQ;AAFE,OAAA,WAAA;AAGhB,OAAK,OAAO;;;AAIhB,IAAa,oBAAb,cAAuC,iBAAiB;CACtD,YAAY,UAAkC;AAC5C,QACE,qBAAqB,SAAS,sEAC/B;AAHyB,OAAA,WAAA;AAI1B,OAAK,OAAO;;;AAIhB,IAAa,oBAAb,cAAuC,iBAAiB;CACtD,YACE,UACA,QACA;EAGA,MAAM,YAAY,kBAAkB,QAAQ,OAAO,YAAY,OAAO,OAAO;AAC7E,QAAM,gCAAgC,SAAS,KAAK,UAAU,4BAA4B;AAN1E,OAAA,WAAA;AACA,OAAA,SAAA;AAMhB,OAAK,OAAO;;;AAIhB,IAAa,wBAAb,cAA2C,iBAAiB;CAC1D,YAAY,cAAsC;AAChD,QACE,aAAa,aAAa,8EAC3B;AAHyB,OAAA,eAAA;AAI1B,OAAK,OAAO;;;AAIhB,IAAa,oBAAb,cAAuC,iBAAiB;CACtD,YACE,UACA,WACA;EACA,MAAM,MAAM,YACR,6BAA6B,SAAS,aAAa,UAAU,0BAC7D,6BAA6B,SAAS;AAC1C,QAAM,IAAI;AANM,OAAA,WAAA;AACA,OAAA,YAAA;AAMhB,OAAK,OAAO;;;AAIhB,IAAa,qBAAb,cAAwC,iBAAiB;CACvD,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;AAIhB,IAAa,oBAAb,cAAuC,iBAAiB;CACtD,YAAY,WAAmC;AAC7C,QAAM,+BAA+B,KAAK,MAAM,YAAY,IAAK,CAAC,6BAA6B;AADrE,OAAA,YAAA;AAE1B,OAAK,OAAO;;;AAIhB,IAAa,qBAAb,cAAwC,iBAAiB;CACvD,cAAc;AACZ,QAAM,2EAA2E;AACjF,OAAK,OAAO"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as createTokenStore } from "./store-57VEqlSz.mjs";
|
|
3
|
+
//#region src/cli/commands/export.ts
|
|
4
|
+
async function exportCommand(storeType) {
|
|
5
|
+
const credentials = await (await createTokenStore(storeType)).list();
|
|
6
|
+
process.stdout.write(JSON.stringify(credentials, null, 2) + "\n");
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { exportCommand };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=export-CpcD-XlM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-CpcD-XlM.mjs","names":[],"sources":["../../src/cli/commands/export.ts"],"sourcesContent":["import { createTokenStore } from \"@/storage/store.ts\";\nimport type { StoreType } from \"@/storage/store.ts\";\n\nexport async function exportCommand(storeType?: StoreType): Promise<void> {\n const store = await createTokenStore(storeType);\n const credentials = await store.list();\n process.stdout.write(JSON.stringify(credentials, null, 2) + \"\\n\");\n}\n"],"mappings":";;;AAGA,eAAsB,cAAc,WAAsC;CAExE,MAAM,cAAc,OADN,MAAM,iBAAiB,UAAU,EACf,MAAM;AACtC,SAAQ,OAAO,MAAM,KAAK,UAAU,aAAa,MAAM,EAAE,GAAG,KAAK"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { n as printSuccess, t as printError } from "./ui-CdGEuLwh.mjs";
|
|
3
|
+
import { t as createTokenStore } from "./store-57VEqlSz.mjs";
|
|
4
|
+
//#region src/cli/commands/import.ts
|
|
5
|
+
async function importCommand(storeType) {
|
|
6
|
+
if (process.stdin.isTTY) process.stderr.write("Reading credentials from stdin (pipe JSON or press Ctrl+D when done)...\n");
|
|
7
|
+
const parts = [];
|
|
8
|
+
for await (const chunk of process.stdin) parts.push(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
9
|
+
const json = parts.join("").trim();
|
|
10
|
+
if (!json) {
|
|
11
|
+
printError("No input received. Pipe a JSON array of credentials to stdin.");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
let credentials;
|
|
15
|
+
try {
|
|
16
|
+
const parsed = JSON.parse(json);
|
|
17
|
+
if (!Array.isArray(parsed)) throw new Error("Input must be a JSON array of credentials");
|
|
18
|
+
for (const item of parsed) {
|
|
19
|
+
if (typeof item !== "object" || item === null || typeof item.tokenSet !== "object" || typeof item.metadata !== "object") throw new Error("Each credential must have a 'tokenSet' and 'metadata' field (StoredCredential format)");
|
|
20
|
+
const meta = item.metadata;
|
|
21
|
+
const ts = item.tokenSet;
|
|
22
|
+
if (!meta?.provider || !meta?.accountId || !ts?.accessToken) throw new Error("Each credential must have metadata.provider, metadata.accountId, and tokenSet.accessToken");
|
|
23
|
+
}
|
|
24
|
+
credentials = parsed;
|
|
25
|
+
} catch (err) {
|
|
26
|
+
printError(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const store = await createTokenStore(storeType);
|
|
30
|
+
let count = 0;
|
|
31
|
+
for (const cred of credentials) {
|
|
32
|
+
await store.set(cred.metadata.provider, cred.metadata.accountId, cred);
|
|
33
|
+
count++;
|
|
34
|
+
}
|
|
35
|
+
printSuccess(`Imported ${count} credential(s).`);
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { importCommand };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=import-BZDRd0Nj.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-BZDRd0Nj.mjs","names":[],"sources":["../../src/cli/commands/import.ts"],"sourcesContent":["import { createTokenStore } from \"@/storage/store.ts\";\nimport type { StoreType } from \"@/storage/store.ts\";\nimport { printError, printSuccess } from \"@/cli/ui.ts\";\nimport type { StoredCredential } from \"@/types.ts\";\n\nexport async function importCommand(storeType?: StoreType): Promise<void> {\n if (process.stdin.isTTY) {\n process.stderr.write(\n \"Reading credentials from stdin (pipe JSON or press Ctrl+D when done)...\\n\",\n );\n }\n\n const parts: string[] = [];\n for await (const chunk of process.stdin) {\n parts.push(typeof chunk === \"string\" ? chunk : (chunk as Buffer).toString(\"utf8\"));\n }\n const json = parts.join(\"\").trim();\n\n if (!json) {\n printError(\"No input received. Pipe a JSON array of credentials to stdin.\");\n process.exit(1);\n }\n\n let credentials: StoredCredential[];\n try {\n const parsed: unknown = JSON.parse(json);\n if (!Array.isArray(parsed)) {\n throw new Error(\"Input must be a JSON array of credentials\");\n }\n // Validate each entry has required fields\n for (const item of parsed) {\n if (\n typeof item !== \"object\" ||\n item === null ||\n typeof (item as Record<string, unknown>).tokenSet !== \"object\" ||\n typeof (item as Record<string, unknown>).metadata !== \"object\"\n ) {\n throw new Error(\n \"Each credential must have a 'tokenSet' and 'metadata' field (StoredCredential format)\",\n );\n }\n const meta = (item as StoredCredential).metadata;\n const ts = (item as StoredCredential).tokenSet;\n if (!meta?.provider || !meta?.accountId || !ts?.accessToken) {\n throw new Error(\n \"Each credential must have metadata.provider, metadata.accountId, and tokenSet.accessToken\",\n );\n }\n }\n credentials = parsed as StoredCredential[];\n } catch (err) {\n printError(`Invalid input: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n const store = await createTokenStore(storeType);\n let count = 0;\n for (const cred of credentials) {\n await store.set(cred.metadata.provider, cred.metadata.accountId, cred);\n count++;\n }\n\n printSuccess(`Imported ${count} credential(s).`);\n}\n"],"mappings":";;;;AAKA,eAAsB,cAAc,WAAsC;AACxE,KAAI,QAAQ,MAAM,MAChB,SAAQ,OAAO,MACb,4EACD;CAGH,MAAM,QAAkB,EAAE;AAC1B,YAAW,MAAM,SAAS,QAAQ,MAChC,OAAM,KAAK,OAAO,UAAU,WAAW,QAAS,MAAiB,SAAS,OAAO,CAAC;CAEpF,MAAM,OAAO,MAAM,KAAK,GAAG,CAAC,MAAM;AAElC,KAAI,CAAC,MAAM;AACT,aAAW,gEAAgE;AAC3E,UAAQ,KAAK,EAAE;;CAGjB,IAAI;AACJ,KAAI;EACF,MAAM,SAAkB,KAAK,MAAM,KAAK;AACxC,MAAI,CAAC,MAAM,QAAQ,OAAO,CACxB,OAAM,IAAI,MAAM,4CAA4C;AAG9D,OAAK,MAAM,QAAQ,QAAQ;AACzB,OACE,OAAO,SAAS,YAChB,SAAS,QACT,OAAQ,KAAiC,aAAa,YACtD,OAAQ,KAAiC,aAAa,SAEtD,OAAM,IAAI,MACR,wFACD;GAEH,MAAM,OAAQ,KAA0B;GACxC,MAAM,KAAM,KAA0B;AACtC,OAAI,CAAC,MAAM,YAAY,CAAC,MAAM,aAAa,CAAC,IAAI,YAC9C,OAAM,IAAI,MACR,4FACD;;AAGL,gBAAc;UACP,KAAK;AACZ,aAAW,kBAAkB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAChF,UAAQ,KAAK,EAAE;;CAGjB,MAAM,QAAQ,MAAM,iBAAiB,UAAU;CAC/C,IAAI,QAAQ;AACZ,MAAK,MAAM,QAAQ,aAAa;AAC9B,QAAM,MAAM,IAAI,KAAK,SAAS,UAAU,KAAK,SAAS,WAAW,KAAK;AACtE;;AAGF,cAAa,YAAY,MAAM,iBAAiB"}
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as printError } from "./ui-CdGEuLwh.mjs";
|
|
3
3
|
import { parseArgs } from "node:util";
|
|
4
|
+
import { EnvHttpProxyAgent, setGlobalDispatcher } from "node:undici";
|
|
5
|
+
//#region src/core/proxy.ts
|
|
6
|
+
/**
|
|
7
|
+
* Initialize HTTP proxy support for all outgoing fetch() calls.
|
|
8
|
+
*
|
|
9
|
+
* Reads HTTPS_PROXY / HTTP_PROXY / NO_PROXY environment variables automatically.
|
|
10
|
+
* If a proxyUrl is provided, it overrides those env vars before installing the dispatcher.
|
|
11
|
+
*
|
|
12
|
+
* Call this once at startup — CLI entry point or library init — before any network requests.
|
|
13
|
+
*
|
|
14
|
+
* @param proxyUrl - Optional explicit proxy URL (e.g. "http://proxy.corp:8080").
|
|
15
|
+
* Sets both HTTPS_PROXY and HTTP_PROXY env vars when provided.
|
|
16
|
+
*/
|
|
17
|
+
function initProxy(proxyUrl) {
|
|
18
|
+
if (proxyUrl) {
|
|
19
|
+
process.env.HTTPS_PROXY = proxyUrl;
|
|
20
|
+
process.env.HTTP_PROXY = proxyUrl;
|
|
21
|
+
}
|
|
22
|
+
setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
4
25
|
//#region src/cli/index.ts
|
|
5
26
|
const HELP = `
|
|
6
27
|
open-sub-auth - OAuth authentication for AI subscription APIs
|
|
@@ -14,9 +35,13 @@ Commands:
|
|
|
14
35
|
status Show status of all stored credentials
|
|
15
36
|
token [provider] Output a valid access token to stdout
|
|
16
37
|
providers List available providers
|
|
38
|
+
export Export all stored credentials to JSON (stdout)
|
|
39
|
+
import Import credentials from JSON (stdin)
|
|
17
40
|
|
|
18
41
|
Options:
|
|
19
42
|
--manual Use manual code paste mode (for headless/CI)
|
|
43
|
+
--proxy <url> HTTP/HTTPS proxy URL (overrides HTTPS_PROXY env var)
|
|
44
|
+
--store <type> Storage backend: auto (default), keychain, or file
|
|
20
45
|
--help, -h Show this help message
|
|
21
46
|
--version, -v Show version
|
|
22
47
|
|
|
@@ -24,14 +49,28 @@ Examples:
|
|
|
24
49
|
open-sub-auth login claude
|
|
25
50
|
open-sub-auth login openai-codex
|
|
26
51
|
open-sub-auth login claude --manual
|
|
52
|
+
open-sub-auth login claude --proxy http://proxy.corp:8080
|
|
27
53
|
open-sub-auth token claude | pbcopy
|
|
28
54
|
open-sub-auth status
|
|
55
|
+
open-sub-auth export > credentials-backup.json
|
|
56
|
+
open-sub-auth import < credentials-backup.json
|
|
29
57
|
`.trim();
|
|
30
58
|
async function main() {
|
|
31
|
-
const { positionals } = parseArgs({
|
|
59
|
+
const { positionals, values } = parseArgs({
|
|
32
60
|
allowPositionals: true,
|
|
33
|
-
strict: false
|
|
61
|
+
strict: false,
|
|
62
|
+
options: {
|
|
63
|
+
proxy: { type: "string" },
|
|
64
|
+
store: { type: "string" }
|
|
65
|
+
}
|
|
34
66
|
});
|
|
67
|
+
initProxy(values.proxy);
|
|
68
|
+
const rawStore = values.store;
|
|
69
|
+
if (rawStore && rawStore !== "auto" && rawStore !== "keychain" && rawStore !== "file") {
|
|
70
|
+
printError(`Invalid --store value "${rawStore}". Valid values: auto, keychain, file`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const storeType = rawStore ?? "auto";
|
|
35
74
|
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
36
75
|
console.log(HELP);
|
|
37
76
|
return;
|
|
@@ -44,28 +83,38 @@ async function main() {
|
|
|
44
83
|
const providerArg = positionals[1];
|
|
45
84
|
switch (command) {
|
|
46
85
|
case "login": {
|
|
47
|
-
const { loginCommand } = await import("./login-
|
|
48
|
-
await loginCommand(providerArg);
|
|
86
|
+
const { loginCommand } = await import("./login-DfG9kqBN.mjs");
|
|
87
|
+
await loginCommand(providerArg, storeType);
|
|
49
88
|
break;
|
|
50
89
|
}
|
|
51
90
|
case "logout": {
|
|
52
|
-
const { logoutCommand } = await import("./logout-
|
|
53
|
-
await logoutCommand(providerArg);
|
|
91
|
+
const { logoutCommand } = await import("./logout-BdnhQ3aw.mjs");
|
|
92
|
+
await logoutCommand(providerArg, storeType);
|
|
54
93
|
break;
|
|
55
94
|
}
|
|
56
95
|
case "status": {
|
|
57
|
-
const { statusCommand } = await import("./status-
|
|
58
|
-
await statusCommand();
|
|
96
|
+
const { statusCommand } = await import("./status-CvktIWmx.mjs");
|
|
97
|
+
await statusCommand(storeType);
|
|
59
98
|
break;
|
|
60
99
|
}
|
|
61
100
|
case "token": {
|
|
62
|
-
const { tokenCommand } = await import("./token-
|
|
63
|
-
await tokenCommand(providerArg);
|
|
101
|
+
const { tokenCommand } = await import("./token-Ce_FmqGM.mjs");
|
|
102
|
+
await tokenCommand(providerArg, storeType);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case "export": {
|
|
106
|
+
const { exportCommand } = await import("./export-CpcD-XlM.mjs");
|
|
107
|
+
await exportCommand(storeType);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "import": {
|
|
111
|
+
const { importCommand } = await import("./import-BZDRd0Nj.mjs");
|
|
112
|
+
await importCommand(storeType);
|
|
64
113
|
break;
|
|
65
114
|
}
|
|
66
115
|
case "providers": {
|
|
67
|
-
await Promise.all([import("./claude-
|
|
68
|
-
const { listProviders } = await import("./registry-
|
|
116
|
+
await Promise.all([import("./claude-Bu4Vb3Sa.mjs"), import("./openai-codex-CKKY1Gu_.mjs")]);
|
|
117
|
+
const { listProviders } = await import("./registry-Dv4TWuqv.mjs").then((n) => n.i);
|
|
69
118
|
const providers = listProviders();
|
|
70
119
|
console.log("Available providers:");
|
|
71
120
|
for (const p of providers) console.log(` - ${p}`);
|
package/dist/cli/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/index.ts"],"sourcesContent":["import { parseArgs } from \"node:util\";\nimport { printError } from \"@/cli/ui.ts\";\n\nconst HELP = `\nopen-sub-auth - OAuth authentication for AI subscription APIs\n\nUsage:\n open-sub-auth <command> [provider] [options]\n\nCommands:\n login [provider] Login to an AI provider via OAuth\n logout [provider] Remove stored tokens for a provider\n status Show status of all stored credentials\n token [provider] Output a valid access token to stdout\n providers List available providers\n\nOptions:\n --manual Use manual code paste mode (for headless/CI)\n --help, -h Show this help message\n --version, -v Show version\n\nExamples:\n open-sub-auth login claude\n open-sub-auth login openai-codex\n open-sub-auth login claude --manual\n open-sub-auth token claude | pbcopy\n open-sub-auth status\n`.trim();\n\nasync function main(): Promise<void> {\n const { positionals } = parseArgs({\n allowPositionals: true,\n strict: false,\n });\n\n if (process.argv.includes(\"--help\") || process.argv.includes(\"-h\")) {\n console.log(HELP);\n return;\n }\n\n if (process.argv.includes(\"--version\") || process.argv.includes(\"-v\")) {\n console.log(\"0.1.0\");\n return;\n }\n\n const command = positionals[0];\n const providerArg = positionals[1];\n\n switch (command) {\n case \"login\": {\n const { loginCommand } = await import(\"@/cli/commands/login.ts\");\n await loginCommand(providerArg);\n break;\n }\n case \"logout\": {\n const { logoutCommand } = await import(\"@/cli/commands/logout.ts\");\n await logoutCommand(providerArg);\n break;\n }\n case \"status\": {\n const { statusCommand } = await import(\"@/cli/commands/status.ts\");\n await statusCommand();\n break;\n }\n case \"token\": {\n const { tokenCommand } = await import(\"@/cli/commands/token.ts\");\n await tokenCommand(providerArg);\n break;\n }\n case \"providers\": {\n await Promise.all([import(\"@/providers/claude.ts\"), import(\"@/providers/openai-codex.ts\")]);\n const { listProviders } = await import(\"@/providers/registry.ts\");\n const providers = listProviders();\n console.log(\"Available providers:\");\n for (const p of providers) {\n console.log(` - ${p}`);\n }\n break;\n }\n default: {\n if (command) {\n printError(`Unknown command: ${command}`);\n }\n console.log(HELP);\n process.exit(command ? 1 : 0);\n }\n }\n}\n\n// Suppress EPIPE errors (e.g. when stdout is piped to a command that exits early)\nprocess.stdout.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") process.exit(0);\n});\n\nmain().catch((err) => {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/core/proxy.ts","../../src/cli/index.ts"],"sourcesContent":["import { EnvHttpProxyAgent, setGlobalDispatcher } from \"node:undici\";\n\n/**\n * Initialize HTTP proxy support for all outgoing fetch() calls.\n *\n * Reads HTTPS_PROXY / HTTP_PROXY / NO_PROXY environment variables automatically.\n * If a proxyUrl is provided, it overrides those env vars before installing the dispatcher.\n *\n * Call this once at startup — CLI entry point or library init — before any network requests.\n *\n * @param proxyUrl - Optional explicit proxy URL (e.g. \"http://proxy.corp:8080\").\n * Sets both HTTPS_PROXY and HTTP_PROXY env vars when provided.\n */\nexport function initProxy(proxyUrl?: string): void {\n if (proxyUrl) {\n process.env.HTTPS_PROXY = proxyUrl;\n process.env.HTTP_PROXY = proxyUrl;\n }\n setGlobalDispatcher(new EnvHttpProxyAgent());\n}\n","import { parseArgs } from \"node:util\";\nimport { printError } from \"@/cli/ui.ts\";\nimport { initProxy } from \"@/core/proxy.ts\";\nimport type { StoreType } from \"@/storage/store.ts\";\n\nconst HELP = `\nopen-sub-auth - OAuth authentication for AI subscription APIs\n\nUsage:\n open-sub-auth <command> [provider] [options]\n\nCommands:\n login [provider] Login to an AI provider via OAuth\n logout [provider] Remove stored tokens for a provider\n status Show status of all stored credentials\n token [provider] Output a valid access token to stdout\n providers List available providers\n export Export all stored credentials to JSON (stdout)\n import Import credentials from JSON (stdin)\n\nOptions:\n --manual Use manual code paste mode (for headless/CI)\n --proxy <url> HTTP/HTTPS proxy URL (overrides HTTPS_PROXY env var)\n --store <type> Storage backend: auto (default), keychain, or file\n --help, -h Show this help message\n --version, -v Show version\n\nExamples:\n open-sub-auth login claude\n open-sub-auth login openai-codex\n open-sub-auth login claude --manual\n open-sub-auth login claude --proxy http://proxy.corp:8080\n open-sub-auth token claude | pbcopy\n open-sub-auth status\n open-sub-auth export > credentials-backup.json\n open-sub-auth import < credentials-backup.json\n`.trim();\n\nasync function main(): Promise<void> {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n strict: false,\n options: {\n proxy: { type: \"string\" },\n store: { type: \"string\" },\n },\n });\n\n // Initialize proxy support before any network requests.\n // Reads HTTPS_PROXY / HTTP_PROXY / NO_PROXY env vars; --proxy overrides them.\n initProxy(values.proxy as string | undefined);\n\n const rawStore = values.store as string | undefined;\n if (rawStore && rawStore !== \"auto\" && rawStore !== \"keychain\" && rawStore !== \"file\") {\n printError(`Invalid --store value \"${rawStore}\". Valid values: auto, keychain, file`);\n process.exit(1);\n }\n const storeType = (rawStore as StoreType | undefined) ?? \"auto\";\n\n if (process.argv.includes(\"--help\") || process.argv.includes(\"-h\")) {\n console.log(HELP);\n return;\n }\n\n if (process.argv.includes(\"--version\") || process.argv.includes(\"-v\")) {\n console.log(\"0.1.0\");\n return;\n }\n\n const command = positionals[0];\n const providerArg = positionals[1];\n\n switch (command) {\n case \"login\": {\n const { loginCommand } = await import(\"@/cli/commands/login.ts\");\n await loginCommand(providerArg, storeType);\n break;\n }\n case \"logout\": {\n const { logoutCommand } = await import(\"@/cli/commands/logout.ts\");\n await logoutCommand(providerArg, storeType);\n break;\n }\n case \"status\": {\n const { statusCommand } = await import(\"@/cli/commands/status.ts\");\n await statusCommand(storeType);\n break;\n }\n case \"token\": {\n const { tokenCommand } = await import(\"@/cli/commands/token.ts\");\n await tokenCommand(providerArg, storeType);\n break;\n }\n case \"export\": {\n const { exportCommand } = await import(\"@/cli/commands/export.ts\");\n await exportCommand(storeType);\n break;\n }\n case \"import\": {\n const { importCommand } = await import(\"@/cli/commands/import.ts\");\n await importCommand(storeType);\n break;\n }\n case \"providers\": {\n await Promise.all([import(\"@/providers/claude.ts\"), import(\"@/providers/openai-codex.ts\")]);\n const { listProviders } = await import(\"@/providers/registry.ts\");\n const providers = listProviders();\n console.log(\"Available providers:\");\n for (const p of providers) {\n console.log(` - ${p}`);\n }\n break;\n }\n default: {\n if (command) {\n printError(`Unknown command: ${command}`);\n }\n console.log(HELP);\n process.exit(command ? 1 : 0);\n }\n }\n}\n\n// Suppress EPIPE errors (e.g. when stdout is piped to a command that exits early)\nprocess.stdout.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") process.exit(0);\n});\n\nmain().catch((err) => {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;AAaA,SAAgB,UAAU,UAAyB;AACjD,KAAI,UAAU;AACZ,UAAQ,IAAI,cAAc;AAC1B,UAAQ,IAAI,aAAa;;AAE3B,qBAAoB,IAAI,mBAAmB,CAAC;;;;ACb9C,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BX,MAAM;AAER,eAAe,OAAsB;CACnC,MAAM,EAAE,aAAa,WAAW,UAAU;EACxC,kBAAkB;EAClB,QAAQ;EACR,SAAS;GACP,OAAO,EAAE,MAAM,UAAU;GACzB,OAAO,EAAE,MAAM,UAAU;GAC1B;EACF,CAAC;AAIF,WAAU,OAAO,MAA4B;CAE7C,MAAM,WAAW,OAAO;AACxB,KAAI,YAAY,aAAa,UAAU,aAAa,cAAc,aAAa,QAAQ;AACrF,aAAW,0BAA0B,SAAS,uCAAuC;AACrF,UAAQ,KAAK,EAAE;;CAEjB,MAAM,YAAa,YAAsC;AAEzD,KAAI,QAAQ,KAAK,SAAS,SAAS,IAAI,QAAQ,KAAK,SAAS,KAAK,EAAE;AAClE,UAAQ,IAAI,KAAK;AACjB;;AAGF,KAAI,QAAQ,KAAK,SAAS,YAAY,IAAI,QAAQ,KAAK,SAAS,KAAK,EAAE;AACrE,UAAQ,IAAI,QAAQ;AACpB;;CAGF,MAAM,UAAU,YAAY;CAC5B,MAAM,cAAc,YAAY;AAEhC,SAAQ,SAAR;EACE,KAAK,SAAS;GACZ,MAAM,EAAE,iBAAiB,MAAM,OAAO;AACtC,SAAM,aAAa,aAAa,UAAU;AAC1C;;EAEF,KAAK,UAAU;GACb,MAAM,EAAE,kBAAkB,MAAM,OAAO;AACvC,SAAM,cAAc,aAAa,UAAU;AAC3C;;EAEF,KAAK,UAAU;GACb,MAAM,EAAE,kBAAkB,MAAM,OAAO;AACvC,SAAM,cAAc,UAAU;AAC9B;;EAEF,KAAK,SAAS;GACZ,MAAM,EAAE,iBAAiB,MAAM,OAAO;AACtC,SAAM,aAAa,aAAa,UAAU;AAC1C;;EAEF,KAAK,UAAU;GACb,MAAM,EAAE,kBAAkB,MAAM,OAAO;AACvC,SAAM,cAAc,UAAU;AAC9B;;EAEF,KAAK,UAAU;GACb,MAAM,EAAE,kBAAkB,MAAM,OAAO;AACvC,SAAM,cAAc,UAAU;AAC9B;;EAEF,KAAK,aAAa;AAChB,SAAM,QAAQ,IAAI,CAAC,OAAO,0BAA0B,OAAO,+BAA+B,CAAC;GAC3F,MAAM,EAAE,kBAAkB,MAAM,OAAO,2BAAA,MAAA,MAAA,EAAA,EAAA;GACvC,MAAM,YAAY,eAAe;AACjC,WAAQ,IAAI,uBAAuB;AACnC,QAAK,MAAM,KAAK,UACd,SAAQ,IAAI,OAAO,IAAI;AAEzB;;EAEF;AACE,OAAI,QACF,YAAW,oBAAoB,UAAU;AAE3C,WAAQ,IAAI,KAAK;AACjB,WAAQ,KAAK,UAAU,IAAI,EAAE;;;AAMnC,QAAQ,OAAO,GAAG,UAAU,QAA+B;AACzD,KAAI,IAAI,SAAS,QAAS,SAAQ,KAAK,EAAE;EACzC;AAEF,MAAM,CAAC,OAAO,QAAQ;AACpB,YAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC5D,SAAQ,KAAK,EAAE;EACf"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as listProviders } from "./registry-
|
|
2
|
+
import { n as listProviders } from "./registry-Dv4TWuqv.mjs";
|
|
3
3
|
import { n as printSuccess, r as promptSelect, t as printError } from "./ui-CdGEuLwh.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { t as createTokenStore } from "./store-57VEqlSz.mjs";
|
|
5
|
+
import { t as TokenManager } from "./manager-C-RjavF0.mjs";
|
|
5
6
|
//#region src/cli/commands/login.ts
|
|
6
|
-
async function loginCommand(providerArg) {
|
|
7
|
-
await Promise.all([import("./claude-
|
|
7
|
+
async function loginCommand(providerArg, storeType) {
|
|
8
|
+
await Promise.all([import("./claude-Bu4Vb3Sa.mjs"), import("./openai-codex-CKKY1Gu_.mjs")]);
|
|
8
9
|
const providers = listProviders();
|
|
9
10
|
if (providers.length === 0) {
|
|
10
11
|
printError("No providers registered.");
|
|
@@ -17,7 +18,7 @@ async function loginCommand(providerArg) {
|
|
|
17
18
|
process.exit(1);
|
|
18
19
|
}
|
|
19
20
|
const manual = process.argv.includes("--manual");
|
|
20
|
-
const manager = new TokenManager(await createTokenStore());
|
|
21
|
+
const manager = new TokenManager(await createTokenStore(storeType));
|
|
21
22
|
try {
|
|
22
23
|
const credential = await manager.login(providerName, { manual });
|
|
23
24
|
const label = credential.metadata.accountLabel ? ` (${credential.metadata.accountLabel})` : "";
|
|
@@ -30,4 +31,4 @@ async function loginCommand(providerArg) {
|
|
|
30
31
|
//#endregion
|
|
31
32
|
export { loginCommand };
|
|
32
33
|
|
|
33
|
-
//# sourceMappingURL=login-
|
|
34
|
+
//# sourceMappingURL=login-DfG9kqBN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-DfG9kqBN.mjs","names":[],"sources":["../../src/cli/commands/login.ts"],"sourcesContent":["import { listProviders } from \"@/providers/registry.ts\";\nimport { createTokenStore } from \"@/storage/store.ts\";\nimport type { StoreType } from \"@/storage/store.ts\";\nimport { TokenManager } from \"@/token/manager.ts\";\nimport { promptSelect, printError, printSuccess } from \"@/cli/ui.ts\";\n\nexport async function loginCommand(providerArg?: string, storeType?: StoreType): Promise<void> {\n await Promise.all([import(\"@/providers/claude.ts\"), import(\"@/providers/openai-codex.ts\")]);\n\n const providers = listProviders();\n if (providers.length === 0) {\n printError(\"No providers registered.\");\n process.exit(1);\n }\n\n let providerName = providerArg;\n if (!providerName) {\n providerName = await promptSelect(\"Select a provider:\", providers);\n }\n\n if (!providers.includes(providerName)) {\n printError(`Unknown provider \"${providerName}\". Available: ${providers.join(\", \")}`);\n process.exit(1);\n }\n\n const manual = process.argv.includes(\"--manual\");\n const store = await createTokenStore(storeType);\n const manager = new TokenManager(store);\n\n try {\n const credential = await manager.login(providerName, { manual });\n const label = credential.metadata.accountLabel ? ` (${credential.metadata.accountLabel})` : \"\";\n printSuccess(`Logged in to ${providerName}${label}. Token stored securely.`);\n } catch (err) {\n printError(`Login failed: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;AAMA,eAAsB,aAAa,aAAsB,WAAsC;AAC7F,OAAM,QAAQ,IAAI,CAAC,OAAO,0BAA0B,OAAO,+BAA+B,CAAC;CAE3F,MAAM,YAAY,eAAe;AACjC,KAAI,UAAU,WAAW,GAAG;AAC1B,aAAW,2BAA2B;AACtC,UAAQ,KAAK,EAAE;;CAGjB,IAAI,eAAe;AACnB,KAAI,CAAC,aACH,gBAAe,MAAM,aAAa,sBAAsB,UAAU;AAGpE,KAAI,CAAC,UAAU,SAAS,aAAa,EAAE;AACrC,aAAW,qBAAqB,aAAa,gBAAgB,UAAU,KAAK,KAAK,GAAG;AACpF,UAAQ,KAAK,EAAE;;CAGjB,MAAM,SAAS,QAAQ,KAAK,SAAS,WAAW;CAEhD,MAAM,UAAU,IAAI,aADN,MAAM,iBAAiB,UAAU,CACR;AAEvC,KAAI;EACF,MAAM,aAAa,MAAM,QAAQ,MAAM,cAAc,EAAE,QAAQ,CAAC;EAChE,MAAM,QAAQ,WAAW,SAAS,eAAe,KAAK,WAAW,SAAS,aAAa,KAAK;AAC5F,eAAa,gBAAgB,eAAe,MAAM,0BAA0B;UACrE,KAAK;AACZ,aAAW,iBAAiB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAC/E,UAAQ,KAAK,EAAE"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as listProviders } from "./registry-
|
|
2
|
+
import { n as listProviders } from "./registry-Dv4TWuqv.mjs";
|
|
3
3
|
import { n as printSuccess, r as promptSelect, t as printError } from "./ui-CdGEuLwh.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { t as createTokenStore } from "./store-57VEqlSz.mjs";
|
|
5
|
+
import { t as TokenManager } from "./manager-C-RjavF0.mjs";
|
|
5
6
|
//#region src/cli/commands/logout.ts
|
|
6
|
-
async function logoutCommand(providerArg) {
|
|
7
|
-
await Promise.all([import("./claude-
|
|
7
|
+
async function logoutCommand(providerArg, storeType) {
|
|
8
|
+
await Promise.all([import("./claude-Bu4Vb3Sa.mjs"), import("./openai-codex-CKKY1Gu_.mjs")]);
|
|
8
9
|
const providers = listProviders();
|
|
9
10
|
let providerName = providerArg;
|
|
10
11
|
if (!providerName) providerName = await promptSelect("Select a provider to logout:", providers);
|
|
11
|
-
const manager = new TokenManager(await createTokenStore());
|
|
12
|
+
const manager = new TokenManager(await createTokenStore(storeType));
|
|
12
13
|
try {
|
|
13
14
|
await manager.logout(providerName);
|
|
14
15
|
printSuccess(`Logged out of ${providerName}. Stored tokens removed.`);
|
|
@@ -20,4 +21,4 @@ async function logoutCommand(providerArg) {
|
|
|
20
21
|
//#endregion
|
|
21
22
|
export { logoutCommand };
|
|
22
23
|
|
|
23
|
-
//# sourceMappingURL=logout-
|
|
24
|
+
//# sourceMappingURL=logout-BdnhQ3aw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout-BdnhQ3aw.mjs","names":[],"sources":["../../src/cli/commands/logout.ts"],"sourcesContent":["import { listProviders } from \"@/providers/registry.ts\";\nimport { createTokenStore } from \"@/storage/store.ts\";\nimport type { StoreType } from \"@/storage/store.ts\";\nimport { TokenManager } from \"@/token/manager.ts\";\nimport { printError, printSuccess, promptSelect } from \"@/cli/ui.ts\";\n\nexport async function logoutCommand(providerArg?: string, storeType?: StoreType): Promise<void> {\n await Promise.all([import(\"@/providers/claude.ts\"), import(\"@/providers/openai-codex.ts\")]);\n\n const providers = listProviders();\n let providerName = providerArg;\n if (!providerName) {\n providerName = await promptSelect(\"Select a provider to logout:\", providers);\n }\n\n const store = await createTokenStore(storeType);\n const manager = new TokenManager(store);\n\n try {\n await manager.logout(providerName);\n printSuccess(`Logged out of ${providerName}. Stored tokens removed.`);\n } catch (err) {\n printError(`Logout failed: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;AAMA,eAAsB,cAAc,aAAsB,WAAsC;AAC9F,OAAM,QAAQ,IAAI,CAAC,OAAO,0BAA0B,OAAO,+BAA+B,CAAC;CAE3F,MAAM,YAAY,eAAe;CACjC,IAAI,eAAe;AACnB,KAAI,CAAC,aACH,gBAAe,MAAM,aAAa,gCAAgC,UAAU;CAI9E,MAAM,UAAU,IAAI,aADN,MAAM,iBAAiB,UAAU,CACR;AAEvC,KAAI;AACF,QAAM,QAAQ,OAAO,aAAa;AAClC,eAAa,iBAAiB,aAAa,0BAA0B;UAC9D,KAAK;AACZ,aAAW,kBAAkB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAChF,UAAQ,KAAK,EAAE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as getProvider } from "./registry-Dv4TWuqv.mjs";
|
|
3
|
+
import { c as TokenRefreshError, n as NoCredentialError, s as TokenExpiredError } from "./errors-BQeS4Q64.mjs";
|
|
4
|
+
//#region src/token/manager.ts
|
|
5
|
+
/** Buffer time before expiry to trigger refresh (5 minutes) */
|
|
6
|
+
const REFRESH_BUFFER_MS = 300 * 1e3;
|
|
7
|
+
/** Central token lifecycle manager */
|
|
8
|
+
var TokenManager = class {
|
|
9
|
+
store;
|
|
10
|
+
/** Per-provider+account mutex to prevent concurrent refreshes */
|
|
11
|
+
refreshLocks = /* @__PURE__ */ new Map();
|
|
12
|
+
constructor(store) {
|
|
13
|
+
this.store = store;
|
|
14
|
+
}
|
|
15
|
+
/** Run the interactive login flow for a provider, store the tokens */
|
|
16
|
+
async login(providerName, options) {
|
|
17
|
+
const provider = getProvider(providerName);
|
|
18
|
+
const tokenSet = await provider.login(options);
|
|
19
|
+
const accountId = provider.getAccountId(tokenSet);
|
|
20
|
+
const accountLabel = provider.getAccountLabel?.(tokenSet);
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
const credential = {
|
|
23
|
+
tokenSet,
|
|
24
|
+
metadata: {
|
|
25
|
+
provider: providerName,
|
|
26
|
+
accountId,
|
|
27
|
+
accountLabel,
|
|
28
|
+
createdAt: now,
|
|
29
|
+
lastRefreshedAt: now
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
await this.store.set(providerName, accountId, credential);
|
|
33
|
+
return credential;
|
|
34
|
+
}
|
|
35
|
+
/** Get a valid access token, refreshing if needed */
|
|
36
|
+
async getToken(providerName, accountId) {
|
|
37
|
+
const credential = await this.resolveCredential(providerName, accountId);
|
|
38
|
+
const { tokenSet } = credential;
|
|
39
|
+
if (this.isTokenValid(tokenSet.expiresAt)) return tokenSet.accessToken;
|
|
40
|
+
if (!tokenSet.refreshToken) throw new TokenExpiredError(providerName);
|
|
41
|
+
await this.refreshWithLock(providerName, credential);
|
|
42
|
+
const refreshed = await this.store.get(providerName, credential.metadata.accountId);
|
|
43
|
+
if (!refreshed) throw new TokenExpiredError(providerName);
|
|
44
|
+
return refreshed.tokenSet.accessToken;
|
|
45
|
+
}
|
|
46
|
+
/** Get authenticated headers for API calls */
|
|
47
|
+
async getAuthHeaders(providerName, accountId) {
|
|
48
|
+
const token = await this.getToken(providerName, accountId);
|
|
49
|
+
return getProvider(providerName).getAuthHeaders(token);
|
|
50
|
+
}
|
|
51
|
+
/** Remove stored tokens for a provider */
|
|
52
|
+
async logout(providerName, accountId) {
|
|
53
|
+
if (accountId) await this.store.delete(providerName, accountId);
|
|
54
|
+
else {
|
|
55
|
+
const credentials = await this.store.list(providerName);
|
|
56
|
+
for (const cred of credentials) await this.store.delete(providerName, cred.metadata.accountId);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Get status of all stored credentials */
|
|
60
|
+
async status() {
|
|
61
|
+
return (await this.store.list()).map((cred) => {
|
|
62
|
+
let displayName = cred.metadata.provider;
|
|
63
|
+
try {
|
|
64
|
+
displayName = getProvider(cred.metadata.provider).config.displayName;
|
|
65
|
+
} catch {}
|
|
66
|
+
return {
|
|
67
|
+
provider: cred.metadata.provider,
|
|
68
|
+
displayName,
|
|
69
|
+
accountId: cred.metadata.accountId,
|
|
70
|
+
accountLabel: cred.metadata.accountLabel,
|
|
71
|
+
isExpired: !this.isTokenValid(cred.tokenSet.expiresAt),
|
|
72
|
+
expiresAt: cred.tokenSet.expiresAt,
|
|
73
|
+
hasRefreshToken: cred.tokenSet.refreshToken !== null
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
isTokenValid(expiresAt) {
|
|
78
|
+
return Date.now() + REFRESH_BUFFER_MS < expiresAt;
|
|
79
|
+
}
|
|
80
|
+
async resolveCredential(providerName, accountId) {
|
|
81
|
+
if (accountId) {
|
|
82
|
+
const credential = await this.store.get(providerName, accountId);
|
|
83
|
+
if (!credential) throw new NoCredentialError(providerName, accountId);
|
|
84
|
+
return credential;
|
|
85
|
+
}
|
|
86
|
+
const credentials = await this.store.list(providerName);
|
|
87
|
+
if (credentials.length === 0) throw new NoCredentialError(providerName);
|
|
88
|
+
return credentials.sort((a, b) => b.metadata.lastRefreshedAt - a.metadata.lastRefreshedAt)[0];
|
|
89
|
+
}
|
|
90
|
+
async refreshWithLock(providerName, credential) {
|
|
91
|
+
const lockKey = `${providerName}::${credential.metadata.accountId}`;
|
|
92
|
+
const existingLock = this.refreshLocks.get(lockKey);
|
|
93
|
+
if (existingLock) {
|
|
94
|
+
await existingLock;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const refreshPromise = this.doRefresh(providerName, credential);
|
|
98
|
+
this.refreshLocks.set(lockKey, refreshPromise);
|
|
99
|
+
try {
|
|
100
|
+
await refreshPromise;
|
|
101
|
+
} finally {
|
|
102
|
+
this.refreshLocks.delete(lockKey);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async doRefresh(providerName, credential) {
|
|
106
|
+
const provider = getProvider(providerName);
|
|
107
|
+
const { refreshToken } = credential.tokenSet;
|
|
108
|
+
if (!refreshToken) throw new TokenExpiredError(providerName);
|
|
109
|
+
let newTokenSet;
|
|
110
|
+
try {
|
|
111
|
+
newTokenSet = await provider.refresh(refreshToken);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
throw new TokenRefreshError(providerName, err);
|
|
114
|
+
}
|
|
115
|
+
if (!newTokenSet.refreshToken && refreshToken) newTokenSet.refreshToken = refreshToken;
|
|
116
|
+
const updatedCredential = {
|
|
117
|
+
tokenSet: newTokenSet,
|
|
118
|
+
metadata: {
|
|
119
|
+
...credential.metadata,
|
|
120
|
+
lastRefreshedAt: Date.now()
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
await this.store.set(providerName, credential.metadata.accountId, updatedCredential);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
//#endregion
|
|
127
|
+
export { TokenManager as t };
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=manager-C-RjavF0.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager-C-RjavF0.mjs","names":[],"sources":["../../src/token/manager.ts"],"sourcesContent":["import { NoCredentialError, TokenExpiredError, TokenRefreshError } from \"@/errors.ts\";\nimport { getProvider } from \"@/providers/registry.ts\";\nimport type {\n AuthHeaders,\n CredentialStatus,\n LoginOptions,\n StoredCredential,\n TokenStore,\n} from \"@/types.ts\";\n\n/** Buffer time before expiry to trigger refresh (5 minutes) */\nconst REFRESH_BUFFER_MS = 5 * 60 * 1000;\n\n/** Central token lifecycle manager */\nexport class TokenManager {\n private readonly store: TokenStore;\n /** Per-provider+account mutex to prevent concurrent refreshes */\n private readonly refreshLocks = new Map<string, Promise<void>>();\n\n constructor(store: TokenStore) {\n this.store = store;\n }\n\n /** Run the interactive login flow for a provider, store the tokens */\n async login(providerName: string, options?: LoginOptions): Promise<StoredCredential> {\n const provider = getProvider(providerName);\n const tokenSet = await provider.login(options);\n\n const accountId = provider.getAccountId(tokenSet);\n const accountLabel = provider.getAccountLabel?.(tokenSet);\n const now = Date.now();\n\n const credential: StoredCredential = {\n tokenSet,\n metadata: {\n provider: providerName,\n accountId,\n accountLabel,\n createdAt: now,\n lastRefreshedAt: now,\n },\n };\n\n await this.store.set(providerName, accountId, credential);\n return credential;\n }\n\n /** Get a valid access token, refreshing if needed */\n async getToken(providerName: string, accountId?: string): Promise<string> {\n const credential = await this.resolveCredential(providerName, accountId);\n const { tokenSet } = credential;\n\n if (this.isTokenValid(tokenSet.expiresAt)) {\n return tokenSet.accessToken;\n }\n\n // Token expired or near-expiry — try to refresh\n if (!tokenSet.refreshToken) {\n throw new TokenExpiredError(providerName);\n }\n\n await this.refreshWithLock(providerName, credential);\n\n // Re-read from store after refresh\n const refreshed = await this.store.get(providerName, credential.metadata.accountId);\n if (!refreshed) {\n throw new TokenExpiredError(providerName);\n }\n return refreshed.tokenSet.accessToken;\n }\n\n /** Get authenticated headers for API calls */\n async getAuthHeaders(providerName: string, accountId?: string): Promise<AuthHeaders> {\n const token = await this.getToken(providerName, accountId);\n const provider = getProvider(providerName);\n return provider.getAuthHeaders(token);\n }\n\n /** Remove stored tokens for a provider */\n async logout(providerName: string, accountId?: string): Promise<void> {\n if (accountId) {\n await this.store.delete(providerName, accountId);\n } else {\n const credentials = await this.store.list(providerName);\n for (const cred of credentials) {\n await this.store.delete(providerName, cred.metadata.accountId);\n }\n }\n }\n\n /** Get status of all stored credentials */\n async status(): Promise<CredentialStatus[]> {\n const credentials = await this.store.list();\n return credentials.map((cred) => {\n let displayName = cred.metadata.provider;\n try {\n const provider = getProvider(cred.metadata.provider);\n displayName = provider.config.displayName;\n } catch {\n // Unknown provider, use raw name\n }\n\n return {\n provider: cred.metadata.provider,\n displayName,\n accountId: cred.metadata.accountId,\n accountLabel: cred.metadata.accountLabel,\n isExpired: !this.isTokenValid(cred.tokenSet.expiresAt),\n expiresAt: cred.tokenSet.expiresAt,\n hasRefreshToken: cred.tokenSet.refreshToken !== null,\n };\n });\n }\n\n private isTokenValid(expiresAt: number): boolean {\n return Date.now() + REFRESH_BUFFER_MS < expiresAt;\n }\n\n private async resolveCredential(\n providerName: string,\n accountId?: string,\n ): Promise<StoredCredential> {\n if (accountId) {\n const credential = await this.store.get(providerName, accountId);\n if (!credential) {\n throw new NoCredentialError(providerName, accountId);\n }\n return credential;\n }\n\n // No account specified — find the most recently refreshed one\n const credentials = await this.store.list(providerName);\n if (credentials.length === 0) {\n throw new NoCredentialError(providerName);\n }\n\n return credentials.sort((a, b) => b.metadata.lastRefreshedAt - a.metadata.lastRefreshedAt)[0]!;\n }\n\n private async refreshWithLock(providerName: string, credential: StoredCredential): Promise<void> {\n const lockKey = `${providerName}::${credential.metadata.accountId}`;\n\n // If a refresh is already in progress for this account, wait for it\n const existingLock = this.refreshLocks.get(lockKey);\n if (existingLock) {\n await existingLock;\n return;\n }\n\n const refreshPromise = this.doRefresh(providerName, credential);\n this.refreshLocks.set(lockKey, refreshPromise);\n\n try {\n await refreshPromise;\n } finally {\n this.refreshLocks.delete(lockKey);\n }\n }\n\n private async doRefresh(providerName: string, credential: StoredCredential): Promise<void> {\n const provider = getProvider(providerName);\n const { refreshToken } = credential.tokenSet;\n\n if (!refreshToken) {\n throw new TokenExpiredError(providerName);\n }\n\n let newTokenSet;\n try {\n newTokenSet = await provider.refresh(refreshToken);\n } catch (err) {\n throw new TokenRefreshError(providerName, err);\n }\n\n // Preserve the refresh token if the new response doesn't include one\n if (!newTokenSet.refreshToken && refreshToken) {\n newTokenSet.refreshToken = refreshToken;\n }\n\n const updatedCredential: StoredCredential = {\n tokenSet: newTokenSet,\n metadata: {\n ...credential.metadata,\n lastRefreshedAt: Date.now(),\n },\n };\n\n await this.store.set(providerName, credential.metadata.accountId, updatedCredential);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { i as OAuthTimeoutError, o as StateMismatchError, r as OAuthCallbackError } from "./errors-BQeS4Q64.mjs";
|
|
3
3
|
import { createInterface } from "node:readline";
|
|
4
4
|
import { createHash, randomBytes } from "node:crypto";
|
|
5
5
|
import { platform } from "node:os";
|
|
@@ -200,10 +200,7 @@ async function exchangeCode(config, code, codeVerifier, redirectUri, state) {
|
|
|
200
200
|
headers: { "Content-Type": useJson ? "application/json" : "application/x-www-form-urlencoded" },
|
|
201
201
|
body: useJson ? JSON.stringify(params) : new URLSearchParams(params).toString()
|
|
202
202
|
});
|
|
203
|
-
if (!response.ok) {
|
|
204
|
-
const errorText = await response.text();
|
|
205
|
-
throw new OAuthCallbackError(`Token exchange failed (${response.status}): ${errorText}`);
|
|
206
|
-
}
|
|
203
|
+
if (!response.ok) throw new OAuthCallbackError(`Token exchange failed (HTTP ${response.status})`);
|
|
207
204
|
return parseTokenResponse(await response.json());
|
|
208
205
|
}
|
|
209
206
|
/** Refresh an access token using a refresh token */
|
|
@@ -219,10 +216,7 @@ async function refreshAccessToken(config, refreshToken) {
|
|
|
219
216
|
headers: { "Content-Type": useJson ? "application/json" : "application/x-www-form-urlencoded" },
|
|
220
217
|
body: useJson ? JSON.stringify(params) : new URLSearchParams(params).toString()
|
|
221
218
|
});
|
|
222
|
-
if (!response.ok) {
|
|
223
|
-
const errorText = await response.text();
|
|
224
|
-
throw new OAuthCallbackError(`Token refresh failed (${response.status}): ${errorText}`);
|
|
225
|
-
}
|
|
219
|
+
if (!response.ok) throw new OAuthCallbackError(`Token refresh failed (HTTP ${response.status})`);
|
|
226
220
|
return parseTokenResponse(await response.json());
|
|
227
221
|
}
|
|
228
222
|
/** Execute the full PKCE flow: generate params, open browser, wait for callback, exchange code */
|
|
@@ -279,4 +273,4 @@ function parseTokenResponse(data) {
|
|
|
279
273
|
//#endregion
|
|
280
274
|
export { refreshAccessToken as n, executePKCEFlow as t };
|
|
281
275
|
|
|
282
|
-
//# sourceMappingURL=oauth-pkce-
|
|
276
|
+
//# sourceMappingURL=oauth-pkce-CCKyG5wP.mjs.map
|