mirror of
https://github.com/hanzoai/js-sdk.git
synced 2026-10-30 15:02:31 +00:00
cloud's openapi.yaml now has a `bearer` securityScheme and a top-level
`security`, so regenerating turns 2498 operations from "imports
setBearerAuthToObject and calls it nowhere" into a real
`Authorization: Bearer` write from `configuration.accessToken`. The four
operations marked `security: []` — /v1/models, /v1/models/providers,
/v1/commands, /v1/openapi.json — generate no auth call, so commands-api.ts
is the one api file of 192 without one.
That retires `baseOptions: { headers: { Authorization } }`, which existed
only because a document with no scheme made `accessToken` inert. One field,
one header, one way; examples/client.ts and the docs say so.
examples/models is new and needs no credential, so a reader can run the
client against the live API before holding a key. Measured, not assumed:
models prints 112 models anonymously, hello prints
`sub admin/hanzo-cloud in org hanzo` with an IAM client-credentials token
and 401 invalid_token with a bad one, and money reads the org's own balance
where anonymous reads account "anonymous".
.spec-lock: hanzoai/cloud@113cf7d6, sha256 a50fc96c.
49 lines
2.0 KiB
TypeScript
49 lines
2.0 KiB
TypeScript
// Where the API is, who we are, and how to print a failure. Every flow imports
|
|
// this and nothing else configures a client.
|
|
import { Configuration } from 'hanzoai';
|
|
|
|
/** Default host. `HANZO_BASE_URL` overrides it (staging, a local cloud, a tunnel). */
|
|
export const basePath = process.env.HANZO_BASE_URL ?? 'https://api.hanzo.ai';
|
|
|
|
/** Fail on the unset variable rather than on the 401 it causes three frames later. */
|
|
export function apiKey(): string {
|
|
const key = process.env.HANZO_API_KEY;
|
|
if (!key) {
|
|
throw new Error('HANZO_API_KEY is not set — export an IAM access token or a cloud API key');
|
|
}
|
|
return key;
|
|
}
|
|
|
|
/**
|
|
* The credential goes in `accessToken`, and that is the only place it goes.
|
|
*
|
|
* The document declares one securityScheme — `bearer`, http/bearer — and a
|
|
* top-level `security: [bearer]`, so every operation that does not opt out with
|
|
* `security: []` now generates `await setBearerAuthToObject(header, config)`,
|
|
* which reads this field and writes `Authorization: Bearer <token>`. 2498 call
|
|
* sites across 191 of the 192 api classes.
|
|
*
|
|
* These examples used to set the header by hand through `baseOptions`, because
|
|
* a document with no securityScheme generates no auth code and `accessToken`
|
|
* was inert. That workaround is gone: one field, one header, one way.
|
|
*/
|
|
export const config = (): Configuration =>
|
|
new Configuration({ basePath, accessToken: apiKey() });
|
|
|
|
/** No credential. The four operations the document marks `security: []` take this. */
|
|
export const anon = (): Configuration => new Configuration({ basePath });
|
|
|
|
/**
|
|
* axios buries the server's message in `response.data`; the bare `.message` is
|
|
* always "Request failed with status code 4xx", which says nothing.
|
|
*/
|
|
export function fail(err: unknown): never {
|
|
const e = err as { response?: { status?: number; data?: unknown }; message?: string };
|
|
if (e.response) {
|
|
console.error(`HTTP ${e.response.status}:`, JSON.stringify(e.response.data));
|
|
} else {
|
|
console.error(e.message ?? err);
|
|
}
|
|
process.exit(1);
|
|
}
|