-
Notifications
You must be signed in to change notification settings - Fork 144
Expand file tree
/
Copy pathmain.ts
More file actions
120 lines (99 loc) · 3.87 KB
/
Copy pathmain.ts
File metadata and controls
120 lines (99 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { scanCommandPath, parseFlags } from './args';
import { registry } from './registry';
import { GLOBAL_OPTIONS } from './command';
import { handleError } from './errors/handler';
import { loadConfig, readConfigFile } from './config/loader';
import { detectRegion, saveDetectedRegion } from './config/detect-region';
import { REGIONS, type Region } from './config/schema';
import { checkForUpdate, getPendingUpdateNotification } from './update/checker';
import { loadCredentials } from './auth/credentials';
import { ensureApiKey } from './auth/setup';
import { CLI_VERSION } from './version';
import { ProxyAgent, setGlobalDispatcher } from 'undici';
// Handle Ctrl+C gracefully
process.on('SIGINT', () => {
process.stderr.write('\nInterrupted. Exiting.\n');
process.exit(130);
});
// Handle stdout EPIPE gracefully (e.g., piped to `mpv` that exits early)
process.stdout.on('error', (e: NodeJS.ErrnoException) => {
if (e.code === 'EPIPE') process.exit(0);
else throw e;
});
// Commands that manage their own auth or need no key
const NO_AUTH_SETUP = [
['auth', 'login'],
['auth', 'logout'],
['config', 'show'],
['config', 'set'],
['config', 'export-schema'],
['update'],
];
async function main() {
const argv = process.argv.slice(2);
if (argv.includes('--version') || argv.includes('-v')) {
console.log(`mmx ${CLI_VERSION}`);
process.exit(0);
}
const commandPath = scanCommandPath(argv, GLOBAL_OPTIONS);
// Proxy: env vars take precedence over config file
const rawConfig = readConfigFile();
const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy
|| process.env.HTTP_PROXY || process.env.http_proxy
|| process.env.ALL_PROXY || process.env.all_proxy
|| rawConfig.proxy;
if (proxyUrl) {
setGlobalDispatcher(new ProxyAgent(proxyUrl));
}
if (argv.includes('--help') || argv.includes('-h')) {
const ri = argv.indexOf('--region');
const region = ((ri >= 0 && argv[ri + 1]) || process.env.MINIMAX_REGION || rawConfig.region || 'global') as Region;
registry.printHelp(commandPath, process.stderr, region);
process.exit(0);
}
// No command: help + quota (if logged in) or login guide
if (commandPath.length === 0) {
registry.printHelp([], process.stderr);
const { command: quotaCmd } = registry.resolve(['quota', 'show']);
const flags = parseFlags(argv, [...GLOBAL_OPTIONS, ...(quotaCmd.options ?? [])]);
const config = loadConfig(flags);
const hasKey = !!(config.apiKey || config.fileApiKey);
const hasOAuth = !!(await loadCredentials());
if (hasKey || hasOAuth) {
await quotaCmd.execute(config, flags);
} else {
process.stderr.write(' Not logged in.\n');
process.stderr.write(' mmx auth login --api-key sk-xxxxx\n\n');
}
process.exit(0);
}
const { command, extra } = registry.resolve(commandPath);
const flags = parseFlags(argv, [...GLOBAL_OPTIONS, ...(command.options ?? [])]);
if (extra.length > 0) (flags as Record<string, unknown>)._positional = extra;
const config = loadConfig(flags);
const needsAuthSetup = !NO_AUTH_SETUP.some(
(cmd) => cmd.every((c, i) => commandPath[i] === c),
);
if (needsAuthSetup) {
await ensureApiKey(config);
}
if (config.needsRegionDetection) {
const apiKey = config.apiKey || config.fileApiKey;
if (apiKey) {
const detected = await detectRegion(apiKey);
config.region = detected;
config.baseUrl = REGIONS[detected];
config.needsRegionDetection = false;
await saveDetectedRegion(detected);
}
}
const updateCheckPromise = checkForUpdate(CLI_VERSION).catch(() => {});
await command.execute(config, flags);
await updateCheckPromise;
const newVersion = getPendingUpdateNotification();
if (newVersion && !config.quiet) {
process.stderr.write(`\n Update available: ${newVersion}\n`);
process.stderr.write(` npm update -g mmx-cli\n\n`);
}
}
main().catch(handleError);