@wavespeed/cli 0.2.3 → 0.2.5
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/commands/auth.js +4 -0
- package/dist/lib/api.js +22 -3
- package/package.json +2 -2
package/dist/commands/auth.js
CHANGED
|
@@ -33,6 +33,10 @@ async function readClipboardKey() {
|
|
|
33
33
|
async function validateKey(apiKey, baseUrl) {
|
|
34
34
|
// The platform doesn't expose a dedicated /whoami yet, so we ping a known
|
|
35
35
|
// authenticated endpoint and treat anything that isn't 401/403 as "key works".
|
|
36
|
+
// Note this proves the key is live, not that it can run models: /balance is
|
|
37
|
+
// deliberately open to every key regardless of the creator's org role, so a
|
|
38
|
+
// Billing-created key logs in here and only fails at `run`, which now
|
|
39
|
+
// surfaces the API's explanation of why.
|
|
36
40
|
let res = null;
|
|
37
41
|
try {
|
|
38
42
|
res = await fetch(`${baseUrl}/api/v3/balance`, {
|
package/dist/lib/api.js
CHANGED
|
@@ -47,7 +47,7 @@ export async function fetchModels(opts = {}) {
|
|
|
47
47
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
48
48
|
});
|
|
49
49
|
if (!res.ok) {
|
|
50
|
-
throw
|
|
50
|
+
throw await httpError(res, 'GET', '/api/v3/models');
|
|
51
51
|
}
|
|
52
52
|
const json = (await res.json());
|
|
53
53
|
if (json.code !== 200) {
|
|
@@ -72,10 +72,29 @@ function authHeaders() {
|
|
|
72
72
|
throw new Error('No API key configured. Run `wavespeed login`.');
|
|
73
73
|
return { Authorization: `Bearer ${apiKey}` };
|
|
74
74
|
}
|
|
75
|
+
// Non-2xx responses still carry the platform's error envelope, and for
|
|
76
|
+
// permission failures that body is the whole point: it names the role that
|
|
77
|
+
// created the key and a role whose key would work. Throwing only the status
|
|
78
|
+
// line turned every 403 into an unactionable "403 Forbidden".
|
|
79
|
+
async function httpError(res, method, path) {
|
|
80
|
+
let detail = '';
|
|
81
|
+
try {
|
|
82
|
+
const body = (await res.json());
|
|
83
|
+
if (body?.message) {
|
|
84
|
+
detail = body.error_code ? `${body.message} [${body.error_code}]` : body.message;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
/* non-JSON body (gateway error page, empty response) — fall back below */
|
|
89
|
+
}
|
|
90
|
+
if (detail)
|
|
91
|
+
return new Error(detail);
|
|
92
|
+
return new Error(`${method} ${path} failed: ${res.status} ${res.statusText}`);
|
|
93
|
+
}
|
|
75
94
|
async function apiGet(path) {
|
|
76
95
|
const res = await fetch(`${getBaseUrl()}${path}`, { headers: authHeaders() });
|
|
77
96
|
if (!res.ok)
|
|
78
|
-
throw
|
|
97
|
+
throw await httpError(res, 'GET', path);
|
|
79
98
|
const json = (await res.json());
|
|
80
99
|
if (json.code !== 200)
|
|
81
100
|
throw new Error(json.message || `API returned code ${json.code}`);
|
|
@@ -88,7 +107,7 @@ async function apiPost(path, body) {
|
|
|
88
107
|
body: JSON.stringify(body),
|
|
89
108
|
});
|
|
90
109
|
if (!res.ok)
|
|
91
|
-
throw
|
|
110
|
+
throw await httpError(res, 'POST', path);
|
|
92
111
|
const json = (await res.json());
|
|
93
112
|
if (json.code !== 200)
|
|
94
113
|
throw new Error(json.message || `API returned code ${json.code}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wavespeed/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "WaveSpeed CLI — one command to run any WaveSpeed AI model from your terminal.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"conf": "^13.0.0",
|
|
57
57
|
"open": "^10.1.0",
|
|
58
58
|
"ora": "^8.1.0",
|
|
59
|
-
"wavespeed": "^0.2.
|
|
59
|
+
"wavespeed": "^0.2.6"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/node": "^20.14.0",
|