11import {
2- BailianError ,
3- ExitCode ,
4- chatEndpoint ,
52 defineCommand ,
6- getConfigPath ,
73 isInteractive ,
84 maskToken ,
95 readConfigFile ,
10- requestJson ,
116 writeConfigFile ,
127 type Config ,
138 type GlobalFlags ,
@@ -16,68 +11,11 @@ import { printQuickStart } from "../../output/banner.ts";
1611import { emitBare } from "../../output/output.ts" ;
1712import { promptConfirm } from "../../output/prompt.ts" ;
1813import { printCurrentCommandHelp } from "../../utils/command-help.ts" ;
19- import { resolveConsoleOrigin , runConsoleLogin } from "./login-console.ts" ;
20-
21- const RETRY_DELAY_BASE_MS = 500 ;
22-
23- function canRetry ( err : unknown ) : boolean {
24- if ( err instanceof BailianError ) {
25- if ( err . exitCode === ExitCode . NETWORK || err . exitCode === ExitCode . TIMEOUT ) {
26- return true ;
27- }
28- const status = err . api ?. httpStatus ;
29- return status === 401 || ( status !== undefined && status >= 500 ) ;
30- }
31- if ( err instanceof Error ) {
32- return (
33- err . name === "AbortError" ||
34- err . name === "TimeoutError" ||
35- err . message . includes ( "timed out" ) ||
36- err . message === "fetch failed"
37- ) ;
38- }
39- return false ;
40- }
41-
42- async function validateKeyAndPersist ( config : Config , key : string ) : Promise < void > {
43- process . stderr . write ( "Testing key... " ) ;
44-
45- const testConfig = { ...config , apiKey : key } ;
46- const requestOpts = {
47- url : chatEndpoint ( testConfig . baseUrl ) ,
48- method : "POST" ,
49- timeout : Math . min ( config . timeout , 30 ) ,
50- body : {
51- model : "qwen3.7-max" ,
52- messages : [ { role : "user" , content : "hi" } ] ,
53- max_tokens : 1 ,
54- } ,
55- } ;
56-
57- for ( let attempt = 1 ; attempt <= 3 ; attempt ++ ) {
58- try {
59- await requestJson < unknown > ( testConfig , requestOpts ) ;
60- break ;
61- } catch ( err ) {
62- if ( attempt >= 3 || ! canRetry ( err ) ) {
63- process . stderr . write ( "\n" ) ;
64- throw new BailianError ( "API key validation failed" , ExitCode . AUTH , "Invalid API key." , {
65- cause : err ,
66- } ) ;
67- }
68- // retry delay: 500ms, 1000ms, 2000ms
69- const delayMs = RETRY_DELAY_BASE_MS * 2 ** ( attempt - 1 ) ;
70- await new Promise ( ( resolve ) => setTimeout ( resolve , delayMs ) ) ;
71- }
72- }
73-
74- process . stderr . write ( "Valid\n" ) ;
75-
76- const existing = readConfigFile ( ) as Record < string , unknown > ;
77- existing . api_key = key ;
78- await writeConfigFile ( existing ) ;
79- process . stderr . write ( `Saved to ${ getConfigPath ( ) } \n` ) ;
80- }
14+ import {
15+ resolveConsoleOrigin ,
16+ runConsoleLogin ,
17+ validateAndPersistApiKey ,
18+ } from "./login-console.ts" ;
8119
8220export default defineCommand ( {
8321 name : "auth login" ,
@@ -138,12 +76,12 @@ export default defineCommand({
13876 const effectiveConfig = baseUrl ? { ...config , baseUrl } : config ;
13977
14078 if ( ! config . dryRun ) {
141- await validateKeyAndPersist ( effectiveConfig , key ) ;
14279 if ( baseUrl ) {
14380 const existing = readConfigFile ( ) as Record < string , unknown > ;
14481 existing . base_url = baseUrl ;
14582 await writeConfigFile ( existing ) ;
14683 }
84+ await validateAndPersistApiKey ( effectiveConfig , key , effectiveConfig . baseUrl ) ;
14785 printQuickStart ( ) ;
14886 } else {
14987 emitBare ( "Would validate and save API key." ) ;
0 commit comments