@omelhorsite/sdk 0.4.0 → 0.4.2
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/README.md +4 -4
- package/dist/index.js +59 -52
- package/dist/types/auth/device.d.ts +1 -1
- package/dist/types/auth/index.d.ts +2 -2
- package/dist/types/auth/tokens.d.ts +15 -15
- package/dist/types/client.d.ts +10 -10
- package/dist/types/errors.d.ts +12 -15
- package/dist/types/http.d.ts +74 -118
- package/dist/types/index.d.ts +1 -2
- package/dist/types/local/qr.d.ts +1 -1
- package/dist/types/local/wordlist.d.ts +2 -3
- package/dist/types/resources/account.d.ts +14 -17
- package/dist/types/resources/auth/index.d.ts +1 -1
- package/dist/types/resources/auth/passkeys.d.ts +127 -163
- package/dist/types/resources/auth/sessions.d.ts +110 -152
- package/dist/types/resources/chests.d.ts +27 -31
- package/dist/types/resources/dynamicQrs.d.ts +29 -45
- package/dist/types/resources/forms.d.ts +37 -58
- package/dist/types/resources/jobs.d.ts +28 -40
- package/dist/types/resources/media.d.ts +48 -61
- package/dist/types/resources/music/artists.d.ts +179 -245
- package/dist/types/resources/music/imports.d.ts +160 -303
- package/dist/types/resources/music/index.d.ts +8 -7
- package/dist/types/resources/music/playlists.d.ts +77 -110
- package/dist/types/resources/music/social.d.ts +153 -228
- package/dist/types/resources/music/songs.d.ts +160 -206
- package/dist/types/resources/realtime.d.ts +75 -88
- package/dist/types/resources/shortLinks.d.ts +33 -45
- package/dist/types/resources/storage/upload.d.ts +42 -56
- package/dist/types/resources/storage.d.ts +71 -104
- package/dist/types/resources/tools/backgroundRemoval.d.ts +11 -13
- package/dist/types/resources/tools/captions.d.ts +120 -135
- package/dist/types/resources/tools/index.d.ts +4 -0
- package/dist/types/resources/tools/srMachine.d.ts +114 -0
- package/dist/types/resources/tools/upscale.d.ts +12 -16
- package/dist/types/types.d.ts +29 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ const oms = new Oms({
|
|
|
39
39
|
baseUrl: "http://localhost:3000", // defaults to https://backend.omelhorsite.pt
|
|
40
40
|
fetch: myFetch, // defaults to globalThis.fetch
|
|
41
41
|
headers: { "X-Trace": id }, // merged under per-call headers
|
|
42
|
-
timeoutMs: 30_000, //
|
|
42
|
+
timeoutMs: 30_000, // per attempt; 0 disables
|
|
43
43
|
retry: { maxAttempts: 3 }, // or false to never retry
|
|
44
44
|
clientName: "my-worker/1.0", // becomes X-Oms-Client
|
|
45
45
|
});
|
|
@@ -186,7 +186,7 @@ const done = await oms.tools.transcription.run(
|
|
|
186
186
|
`run` is `create` plus `jobs.wait`. Use `create` on hosts with a wall-clock
|
|
187
187
|
budget or nowhere to hold a wait: start the job, keep the id, pick it up later.
|
|
188
188
|
|
|
189
|
-
Waiting resolves for both `"
|
|
189
|
+
Waiting resolves for both `"complete"` and `"failed"`: a failed job is an
|
|
190
190
|
answer, not a transport error. Check the status before reading the result.
|
|
191
191
|
|
|
192
192
|
```ts
|
|
@@ -194,8 +194,8 @@ const job = await oms.jobs.wait({ id: started.job_id!, watchToken: started.watch
|
|
|
194
194
|
if (job.status === "failed") throw new Error(job.error ?? "the job failed");
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
-
A finished
|
|
198
|
-
|
|
197
|
+
A finished job says `status: "complete"`, not `"completed"`, and the
|
|
198
|
+
downloader spells its own terminal state `"done"`. Compare against the exported
|
|
199
199
|
constants, never against a literal.
|
|
200
200
|
|
|
201
201
|
Check the quota before starting something expensive:
|
package/dist/index.js
CHANGED
|
@@ -12560,11 +12560,9 @@ function songImportProgress(record) {
|
|
|
12560
12560
|
|
|
12561
12561
|
class MusicImportsNamespace extends Resource {
|
|
12562
12562
|
spotify;
|
|
12563
|
-
srMachine;
|
|
12564
12563
|
constructor(http) {
|
|
12565
12564
|
super(http);
|
|
12566
12565
|
this.spotify = new SpotifySyncNamespace(http);
|
|
12567
|
-
this.srMachine = new SRMachineNamespace(http);
|
|
12568
12566
|
}
|
|
12569
12567
|
async list(params = {}, options = {}) {
|
|
12570
12568
|
const base = {
|
|
@@ -12658,48 +12656,6 @@ class SpotifySyncNamespace extends Resource {
|
|
|
12658
12656
|
};
|
|
12659
12657
|
}
|
|
12660
12658
|
}
|
|
12661
|
-
|
|
12662
|
-
class SRMachineNamespace extends Resource {
|
|
12663
|
-
async metadata(url, options = {}) {
|
|
12664
|
-
return this.http.get("/s_r_machine/metadata", {
|
|
12665
|
-
timeoutMs: 120000,
|
|
12666
|
-
...options,
|
|
12667
|
-
query: { url },
|
|
12668
|
-
retry: options.retry ?? false
|
|
12669
|
-
});
|
|
12670
|
-
}
|
|
12671
|
-
async artwork(url, options = {}) {
|
|
12672
|
-
return this.http.download("/s_r_machine/artwork", {
|
|
12673
|
-
timeoutMs: 120000,
|
|
12674
|
-
...options,
|
|
12675
|
-
query: { url },
|
|
12676
|
-
retry: options.retry ?? false
|
|
12677
|
-
});
|
|
12678
|
-
}
|
|
12679
|
-
async audio(url, options = {}) {
|
|
12680
|
-
return this.http.download("/s_r_machine/audio", {
|
|
12681
|
-
timeoutMs: 600000,
|
|
12682
|
-
...options,
|
|
12683
|
-
query: { url },
|
|
12684
|
-
retry: options.retry ?? false
|
|
12685
|
-
});
|
|
12686
|
-
}
|
|
12687
|
-
async convertToOpus(file2, options = {}) {
|
|
12688
|
-
const form = await buildFormData({ file: file2 });
|
|
12689
|
-
const response = await this.http.raw("POST", "/s_r_machine/convert-opus", {
|
|
12690
|
-
timeoutMs: 600000,
|
|
12691
|
-
...options,
|
|
12692
|
-
body: form
|
|
12693
|
-
});
|
|
12694
|
-
const data = await response.blob();
|
|
12695
|
-
return {
|
|
12696
|
-
data,
|
|
12697
|
-
filename: filenameFromDisposition(response.headers.get("content-disposition")),
|
|
12698
|
-
contentType: response.headers.get("content-type") ?? undefined,
|
|
12699
|
-
size: data.size
|
|
12700
|
-
};
|
|
12701
|
-
}
|
|
12702
|
-
}
|
|
12703
12659
|
function spotifySyncProgress(status) {
|
|
12704
12660
|
const playlists = status.sync_progress?.playlists ?? [];
|
|
12705
12661
|
let loaded = 0;
|
|
@@ -12835,7 +12791,7 @@ class MusicPlaylistsNamespace extends Resource {
|
|
|
12835
12791
|
async reorder(id, songIds, options = {}) {
|
|
12836
12792
|
const ids = integerIds(songIds, "songIds");
|
|
12837
12793
|
if (ids.length === 0) {
|
|
12838
|
-
throw new TypeError("reorder needs the complete desired order and refuses an empty array: the
|
|
12794
|
+
throw new TypeError("reorder needs the complete desired order and refuses an empty array: the server answers 500 for it, " + "not 400.");
|
|
12839
12795
|
}
|
|
12840
12796
|
await this.http.post(`/playlists/${encodeURIComponent(String(id))}/reorder`, { song_ids: ids }, options);
|
|
12841
12797
|
}
|
|
@@ -12958,7 +12914,7 @@ function integerIds(ids, field) {
|
|
|
12958
12914
|
return ids.map((raw, index) => {
|
|
12959
12915
|
const value = typeof raw === "string" ? Number(raw) : raw;
|
|
12960
12916
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
12961
|
-
throw new TypeError(`${field}[${index}] is ${JSON.stringify(raw)}, which is not an integer id. Song ids are integers on this ` + "API
|
|
12917
|
+
throw new TypeError(`${field}[${index}] is ${JSON.stringify(raw)}, which is not an integer id. Song ids are integers on this ` + "API and are matched by identity: a string id matches no row, so the request would succeed and " + "change nothing.");
|
|
12962
12918
|
}
|
|
12963
12919
|
return value;
|
|
12964
12920
|
});
|
|
@@ -13553,7 +13509,7 @@ class CableConnectionImpl {
|
|
|
13553
13509
|
const identifier = JSON.stringify(params);
|
|
13554
13510
|
const registration = { handlers, live: true };
|
|
13555
13511
|
if (this.subs.has(identifier)) {
|
|
13556
|
-
throw new OmsNetworkError(`Already subscribed to ${identifier}.
|
|
13512
|
+
throw new OmsNetworkError(`Already subscribed to ${identifier}. Subscriptions are keyed by identifier, so a second one would shadow the first: reuse the handle, or unsubscribe before resubscribing.`);
|
|
13557
13513
|
}
|
|
13558
13514
|
this.subs.set(identifier, registration);
|
|
13559
13515
|
if (this.welcomed)
|
|
@@ -14818,23 +14774,29 @@ class CaptionsNamespace extends Resource {
|
|
|
14818
14774
|
return this.http.get(`/caption_jobs/${encodeURIComponent(id)}`, options);
|
|
14819
14775
|
}
|
|
14820
14776
|
async transcribe(id, input, options = {}) {
|
|
14821
|
-
const started = await this.
|
|
14777
|
+
const started = await this.startTranscribe(id, input, options);
|
|
14778
|
+
return this.settle(id, started, options, "the transcription");
|
|
14779
|
+
}
|
|
14780
|
+
async startTranscribe(id, input, options = {}) {
|
|
14781
|
+
return this.http.post(`/caption_jobs/${encodeURIComponent(id)}/transcribe`, {
|
|
14822
14782
|
start: input.start,
|
|
14823
14783
|
end: input.end,
|
|
14824
14784
|
...input.language === undefined ? {} : { language: input.language }
|
|
14825
14785
|
}, { ...options, retry: options.retry ?? false });
|
|
14826
|
-
return this.settle(id, started, options, "the transcription");
|
|
14827
14786
|
}
|
|
14828
14787
|
async render(id, input = {}, options = {}) {
|
|
14788
|
+
const started = await this.startRender(id, input, options);
|
|
14789
|
+
return this.settle(id, started, options, "the render");
|
|
14790
|
+
}
|
|
14791
|
+
async startRender(id, input = {}, options = {}) {
|
|
14829
14792
|
const words = input.words ?? (await this.get(id, options)).words ?? [];
|
|
14830
14793
|
if (words.length === 0) {
|
|
14831
14794
|
throw new OmsError(`Caption job ${id} has no words to render. Transcribe a window first with transcribe(), ` + `or pass an edited list as \`words\`.`, "conflict");
|
|
14832
14795
|
}
|
|
14833
|
-
|
|
14796
|
+
return this.http.post(`/caption_jobs/${encodeURIComponent(id)}/render`, {
|
|
14834
14797
|
words,
|
|
14835
14798
|
...input.style === undefined ? {} : { style: input.style }
|
|
14836
14799
|
}, { ...options, retry: options.retry ?? false });
|
|
14837
|
-
return this.settle(id, started, options, "the render");
|
|
14838
14800
|
}
|
|
14839
14801
|
async delete(id, options = {}) {
|
|
14840
14802
|
await this.http.delete(`/caption_jobs/${encodeURIComponent(id)}`, options);
|
|
@@ -14861,7 +14823,7 @@ class CaptionsNamespace extends Resource {
|
|
|
14861
14823
|
}
|
|
14862
14824
|
async createChunked(input, options = {}) {
|
|
14863
14825
|
if (isNativeFile(input.video.data)) {
|
|
14864
|
-
throw new OmsError(`Cannot chunk-upload "${input.video.filename}": it is a React Native file descriptor ` + `(${input.video.data.uri}), and the chunked path has to slice the bytes. Use create() for a file ` + "under
|
|
14826
|
+
throw new OmsError(`Cannot chunk-upload "${input.video.filename}": it is a React Native file descriptor ` + `(${input.video.data.uri}), and the chunked path has to slice the bytes. Use create() for a file ` + "under the ~100 MB request cap, or read the video into a Uint8Array first " + "(Expo: `new File(uri).bytes()`) and pass that.", "invalid_request");
|
|
14865
14827
|
}
|
|
14866
14828
|
const { onProgress, onPart, ...request } = options;
|
|
14867
14829
|
const { blob } = await readFileInput(input.video);
|
|
@@ -15136,6 +15098,49 @@ class UpscaleNamespace extends Resource {
|
|
|
15136
15098
|
}
|
|
15137
15099
|
}
|
|
15138
15100
|
|
|
15101
|
+
// src/resources/tools/srMachine.ts
|
|
15102
|
+
class SRMachineNamespace extends Resource {
|
|
15103
|
+
async metadata(url, options = {}) {
|
|
15104
|
+
return this.http.get("/s_r_machine/metadata", {
|
|
15105
|
+
timeoutMs: 120000,
|
|
15106
|
+
...options,
|
|
15107
|
+
query: { url },
|
|
15108
|
+
retry: options.retry ?? false
|
|
15109
|
+
});
|
|
15110
|
+
}
|
|
15111
|
+
async artwork(url, options = {}) {
|
|
15112
|
+
return this.http.download("/s_r_machine/artwork", {
|
|
15113
|
+
timeoutMs: 120000,
|
|
15114
|
+
...options,
|
|
15115
|
+
query: { url },
|
|
15116
|
+
retry: options.retry ?? false
|
|
15117
|
+
});
|
|
15118
|
+
}
|
|
15119
|
+
async audio(url, options = {}) {
|
|
15120
|
+
return this.http.download("/s_r_machine/audio", {
|
|
15121
|
+
timeoutMs: 600000,
|
|
15122
|
+
...options,
|
|
15123
|
+
query: { url },
|
|
15124
|
+
retry: options.retry ?? false
|
|
15125
|
+
});
|
|
15126
|
+
}
|
|
15127
|
+
async convertToOpus(file2, options = {}) {
|
|
15128
|
+
const form = await buildFormData({ file: file2 });
|
|
15129
|
+
const response = await this.http.raw("POST", "/s_r_machine/convert-opus", {
|
|
15130
|
+
timeoutMs: 600000,
|
|
15131
|
+
...options,
|
|
15132
|
+
body: form
|
|
15133
|
+
});
|
|
15134
|
+
const data = await response.blob();
|
|
15135
|
+
return {
|
|
15136
|
+
data,
|
|
15137
|
+
filename: filenameFromDisposition(response.headers.get("content-disposition")),
|
|
15138
|
+
contentType: response.headers.get("content-type") ?? undefined,
|
|
15139
|
+
size: data.size
|
|
15140
|
+
};
|
|
15141
|
+
}
|
|
15142
|
+
}
|
|
15143
|
+
|
|
15139
15144
|
// src/resources/tools/vocalSeparation.ts
|
|
15140
15145
|
function vocalSeparationProgress(record) {
|
|
15141
15146
|
const base = toolProgress(record);
|
|
@@ -15267,6 +15272,7 @@ class ToolsNamespace extends Resource {
|
|
|
15267
15272
|
captions;
|
|
15268
15273
|
jumpstyle;
|
|
15269
15274
|
downloader;
|
|
15275
|
+
srMachine;
|
|
15270
15276
|
constructor(http) {
|
|
15271
15277
|
super(http);
|
|
15272
15278
|
this.backgroundRemoval = new BackgroundRemovalNamespace(http);
|
|
@@ -15276,6 +15282,7 @@ class ToolsNamespace extends Resource {
|
|
|
15276
15282
|
this.captions = new CaptionsNamespace(http);
|
|
15277
15283
|
this.jumpstyle = new JumpstyleNamespace(http);
|
|
15278
15284
|
this.downloader = new DownloaderNamespace(http);
|
|
15285
|
+
this.srMachine = new SRMachineNamespace(http);
|
|
15279
15286
|
}
|
|
15280
15287
|
}
|
|
15281
15288
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OAuth 2.0 Device Authorization Grant (RFC 8628).
|
|
3
3
|
*
|
|
4
|
-
* This is how a
|
|
4
|
+
* This is how a terminal or a headless client signs a person in without ever handling
|
|
5
5
|
* their password: the client asks for a code, the person opens a URL in a real
|
|
6
6
|
* browser and approves, and the client polls the token endpoint until the
|
|
7
7
|
* approval lands.
|
|
@@ -36,7 +36,7 @@ export * from "./device";
|
|
|
36
36
|
export * from "./tokens";
|
|
37
37
|
/** Who the current credential belongs to. */
|
|
38
38
|
export interface WhoAmI {
|
|
39
|
-
/**
|
|
39
|
+
/** The stable user identifier; matches the OIDC `sub` claim. */
|
|
40
40
|
readonly id: string;
|
|
41
41
|
/** Current handle. Mutable - never key anything on it. */
|
|
42
42
|
readonly handle: string;
|
|
@@ -107,7 +107,7 @@ export declare class AuthNamespace extends Resource {
|
|
|
107
107
|
}, options?: RequestOptions): Promise<void>;
|
|
108
108
|
/**
|
|
109
109
|
* Reads the OIDC claims of the current credential from
|
|
110
|
-
* `GET /oauth/userinfo`. `sub` is `
|
|
110
|
+
* `GET /oauth/userinfo`. `sub` is the user's stable `id`.
|
|
111
111
|
*
|
|
112
112
|
* Needs the `openid` scope; without it the answer is 403. Members whose
|
|
113
113
|
* value is null or empty are omitted from the response, so read defensively.
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Token providers: where the transport gets a bearer token from.
|
|
3
3
|
*
|
|
4
4
|
* The core has no storage. A provider is either a constant, or a thing the
|
|
5
|
-
* host wired to its own store (
|
|
5
|
+
* host wired to its own store (a config file, a Worker KV namespace, a
|
|
6
6
|
* browser's memory). Nothing here reads a file or an environment variable.
|
|
7
7
|
*
|
|
8
8
|
* Two credential shapes exist today and both are just bearer tokens on the
|
|
9
9
|
* wire:
|
|
10
|
-
* - a legacy opaque session token (a UUID
|
|
11
|
-
*
|
|
12
|
-
* - an OAuth 2 / OIDC access token
|
|
13
|
-
*
|
|
10
|
+
* - a legacy opaque session token (a UUID), which never expires and carries no
|
|
11
|
+
* scopes;
|
|
12
|
+
* - an OAuth 2 / OIDC access token, which does expire and does carry scopes,
|
|
13
|
+
* and which comes with a refresh token.
|
|
14
14
|
*
|
|
15
15
|
* {@link TokenSet} models the second. The first is just a string.
|
|
16
16
|
*
|
|
@@ -23,7 +23,7 @@ import { OmsError } from "../errors";
|
|
|
23
23
|
import { type ApiClient, type TokenProvider } from "../http";
|
|
24
24
|
import type { RequestOptions } from "../types";
|
|
25
25
|
/**
|
|
26
|
-
* An OAuth 2 token response, as
|
|
26
|
+
* An OAuth 2 token response, as the token endpoint returns it.
|
|
27
27
|
*
|
|
28
28
|
* `expiresAt` is absolute epoch milliseconds, not the `expires_in` seconds the
|
|
29
29
|
* server sends, so a stored set stays correct across a restart.
|
|
@@ -45,8 +45,8 @@ export interface TokenSet {
|
|
|
45
45
|
/** Claims the SDK reads out of an OIDC id token. */
|
|
46
46
|
export interface IdentityClaims {
|
|
47
47
|
/**
|
|
48
|
-
* Stable user identifier: `
|
|
49
|
-
* both of which the user can change.
|
|
48
|
+
* Stable user identifier: the user's `id`, as `oms.account.me()` reports it.
|
|
49
|
+
* Never the handle and never the email, both of which the user can change.
|
|
50
50
|
*/
|
|
51
51
|
readonly sub: string;
|
|
52
52
|
readonly iss?: string;
|
|
@@ -87,8 +87,8 @@ export declare const DEFAULT_REFRESH_SKEW_MS = 60000;
|
|
|
87
87
|
/**
|
|
88
88
|
* Wraps a constant token. This is what `new Oms({ token })` builds.
|
|
89
89
|
*
|
|
90
|
-
* Accepts both credential kinds: an opaque session UUID and
|
|
91
|
-
*
|
|
90
|
+
* Accepts both credential kinds: an opaque session UUID and an OAuth access
|
|
91
|
+
* token look identical on the wire.
|
|
92
92
|
*/
|
|
93
93
|
export declare function staticToken(token: string | null): TokenProvider;
|
|
94
94
|
/**
|
|
@@ -304,8 +304,8 @@ export declare class OmsOAuthError extends OmsError {
|
|
|
304
304
|
* Recognises an OAuth error inside whatever the transport threw.
|
|
305
305
|
*
|
|
306
306
|
* Deliberately narrow: only 400 and 401 bodies are read as OAuth errors. A 429
|
|
307
|
-
*
|
|
308
|
-
*
|
|
307
|
+
* carries the body `{"error":"rate_limited"}`, and that `error` key is NOT an
|
|
308
|
+
* OAuth code - reading it as one abandons a perfectly
|
|
309
309
|
* live device flow. It stays an {@link OmsQuotaError} and the caller handles
|
|
310
310
|
* it as a rate limit.
|
|
311
311
|
*
|
|
@@ -316,8 +316,8 @@ export declare function oauthErrorFrom(thrown: unknown): OmsOAuthError | undefin
|
|
|
316
316
|
export interface InsufficientScope {
|
|
317
317
|
/**
|
|
318
318
|
* The scopes the endpoint needed. EMPTY when the server named none, which
|
|
319
|
-
* means the endpoint
|
|
320
|
-
*
|
|
319
|
+
* means the endpoint accepts no OAuth token at all - a server-side gap, not
|
|
320
|
+
* a client bug. The two cases must read differently to the user.
|
|
321
321
|
*/
|
|
322
322
|
readonly required: string[];
|
|
323
323
|
/** The `realm` parameter, when present. */
|
|
@@ -342,7 +342,7 @@ export declare function readInsufficientScope(error: unknown): InsufficientScope
|
|
|
342
342
|
*
|
|
343
343
|
* The OAuth endpoints do not take JSON, which is why this exists next to
|
|
344
344
|
* `ApiClient.post` rather than using it. Blank values are dropped rather than
|
|
345
|
-
* sent empty, because
|
|
345
|
+
* sent empty, because the server reads `""` as a present-but-invalid parameter.
|
|
346
346
|
*
|
|
347
347
|
* Retries are OFF and stay off. Replaying `POST /oauth/token` after a lost
|
|
348
348
|
* response is not safe: the server may have rotated the refresh token already,
|
package/dist/types/client.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ import type { FetchLike, RetryOptions } from "./types";
|
|
|
41
41
|
* Anything accepted as a credential by {@link Oms}.
|
|
42
42
|
*
|
|
43
43
|
* A bare string is either kind of bearer token the API takes: a legacy opaque
|
|
44
|
-
*
|
|
44
|
+
* session UUID or an OAuth access token. A function is called on every
|
|
45
45
|
* request. A {@link TokenProvider} additionally gets a chance to refresh on a
|
|
46
46
|
* 401 - see `auth/tokens.ts`.
|
|
47
47
|
*/
|
|
@@ -66,7 +66,7 @@ export interface OmsOptions {
|
|
|
66
66
|
* by name.
|
|
67
67
|
*
|
|
68
68
|
* ```ts
|
|
69
|
-
* //
|
|
69
|
+
* // on a first-party page, served from the same site as the API
|
|
70
70
|
* const oms = new Oms({ sessionCookie: true });
|
|
71
71
|
* ```
|
|
72
72
|
*/
|
|
@@ -75,13 +75,13 @@ export interface OmsOptions {
|
|
|
75
75
|
readonly baseUrl?: string;
|
|
76
76
|
/**
|
|
77
77
|
* The fetch to talk through. Defaults to `globalThis.fetch`. Injecting one is
|
|
78
|
-
* how a Worker adds a cache, how a test swaps in a double, and how
|
|
78
|
+
* how a Worker adds a cache, how a test swaps in a double, and how a host
|
|
79
79
|
* adds a proxy - the SDK never patches a global.
|
|
80
80
|
*/
|
|
81
81
|
readonly fetch?: FetchLike;
|
|
82
82
|
/** Headers merged into every request, below per-call headers. */
|
|
83
83
|
readonly headers?: Record<string, string>;
|
|
84
|
-
/** Default deadline for one
|
|
84
|
+
/** Default deadline for one attempt; a retry gets a fresh one. `0` disables it. */
|
|
85
85
|
readonly timeoutMs?: number;
|
|
86
86
|
/** Default backoff policy, or `false` to never retry. */
|
|
87
87
|
readonly retry?: RetryOptions | false;
|
|
@@ -103,10 +103,10 @@ export interface OmsOptions {
|
|
|
103
103
|
*
|
|
104
104
|
* ## Two credentials, two namespaces
|
|
105
105
|
*
|
|
106
|
-
* `oms.sessions` mints the opaque
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
106
|
+
* `oms.sessions` mints the opaque session token, which carries the whole
|
|
107
|
+
* account. `oms.auth` runs OAuth, whose tokens are scoped and, because an
|
|
108
|
+
* endpoint with no declared scope refuses every OAuth token, cannot reach most
|
|
109
|
+
* of the API at all. `oms.realtime` accepts only the first
|
|
110
110
|
* kind. Picking the wrong one shows up as a `403 insufficient_scope`, or on the
|
|
111
111
|
* cable as a connection that is silently anonymous.
|
|
112
112
|
*
|
|
@@ -178,9 +178,9 @@ export declare class Oms {
|
|
|
178
178
|
/** OAuth client registration for anyone, plus the `/admin/*` routes. */
|
|
179
179
|
readonly admin: AdminNamespace;
|
|
180
180
|
/**
|
|
181
|
-
* The
|
|
181
|
+
* The WebSocket connection: playback handoff, jams, notifications, job
|
|
182
182
|
* progress. Opens nothing until {@link RealtimeNamespace.connect} is called,
|
|
183
|
-
* and wants a
|
|
183
|
+
* and wants a session token rather than the client's own credential - see
|
|
184
184
|
* that method for why.
|
|
185
185
|
*/
|
|
186
186
|
readonly realtime: RealtimeNamespace;
|
package/dist/types/errors.d.ts
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
* The API answers with at least four different error body shapes, so anything
|
|
9
9
|
* that reads an error body must go through {@link normalizeErrorBody}:
|
|
10
10
|
*
|
|
11
|
-
* - a bare JSON string: `"Image too large"`
|
|
12
|
-
* - a sentence
|
|
11
|
+
* - a bare JSON string: `"Image too large"`
|
|
12
|
+
* - a validation sentence: `"Name can't be blank and ..."`
|
|
13
13
|
* - an object with `error`: `{"error":"rate_limited","retry_after":37}`
|
|
14
14
|
* - an object of field errors: `{"errors":{"url":["is invalid"]}}`
|
|
15
15
|
* - plain text / HTML: short-link 404 pages, proxy errors
|
|
16
16
|
*/
|
|
17
17
|
/** Machine-readable code carried by every SDK error. */
|
|
18
18
|
export type OmsErrorCode = "api_error" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "invalid_request" | "quota_exceeded" | "rate_limited" | "server_error" | "timeout" | "aborted" | "network" | "unsupported" | "unknown";
|
|
19
|
-
/** Extra context attached to an error, useful for logs
|
|
19
|
+
/** Extra context attached to an error, useful for logs. */
|
|
20
20
|
export interface OmsErrorContext {
|
|
21
21
|
/** HTTP method of the failing request, when there was one. */
|
|
22
22
|
readonly method?: string;
|
|
@@ -38,9 +38,9 @@ export declare class OmsError extends Error {
|
|
|
38
38
|
* This class's own name, as a LITERAL.
|
|
39
39
|
*
|
|
40
40
|
* `this.name = new.target.name` would be the obvious way to do this and it
|
|
41
|
-
* is wrong here: `bun build --minify` renames the classes, so
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* is wrong here: `bun build --minify` renames the classes, so a minified
|
|
42
|
+
* build reported `name: "A"` in its JSON error envelope while a dev run
|
|
43
|
+
* reported `OmsNetworkError`. A minifier renames identifiers, never
|
|
44
44
|
* string literals or property names, so a static literal survives the build.
|
|
45
45
|
*
|
|
46
46
|
* Every subclass shadows this, and `new.target` is the constructor that was
|
|
@@ -95,9 +95,6 @@ export declare class OmsApiError extends OmsError {
|
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
97
97
|
* 401 or 403: the credential is missing, expired, or not allowed to do this.
|
|
98
|
-
*
|
|
99
|
-
* The CLI turns this into "run `oms auth login`"; the MCP server turns it into
|
|
100
|
-
* a device-flow prompt.
|
|
101
98
|
*/
|
|
102
99
|
export declare class OmsAuthError extends OmsApiError {
|
|
103
100
|
static readonly errorName: string;
|
|
@@ -107,10 +104,10 @@ export declare class OmsAuthError extends OmsApiError {
|
|
|
107
104
|
/**
|
|
108
105
|
* 429, or a documented daily-quota rejection.
|
|
109
106
|
*
|
|
110
|
-
* Two different producers land here and they do not look alike:
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
107
|
+
* Two different producers land here and they do not look alike: a rate limit
|
|
108
|
+
* answers `{"error":"rate_limited","retry_after":37}` with a `Retry-After`
|
|
109
|
+
* header, while a daily quota answers a bare string such as
|
|
110
|
+
* `"Daily edit quota reached (5/day)"` with no header at all. Read
|
|
114
111
|
* {@link retryAfterMs}; it is `undefined` in the second case.
|
|
115
112
|
*/
|
|
116
113
|
export declare class OmsQuotaError extends OmsApiError {
|
|
@@ -160,7 +157,7 @@ export interface NormalizedError {
|
|
|
160
157
|
readonly message: string;
|
|
161
158
|
/** A code the server named itself (`{"error":"rate_limited"}`), if any. */
|
|
162
159
|
readonly serverCode: string | undefined;
|
|
163
|
-
/** Per-field messages, when the body was
|
|
160
|
+
/** Per-field messages, when the body was a field-to-messages map. */
|
|
164
161
|
readonly fieldErrors: Record<string, string[]> | undefined;
|
|
165
162
|
}
|
|
166
163
|
/**
|
|
@@ -179,7 +176,7 @@ export interface NormalizedError {
|
|
|
179
176
|
export declare function normalizeErrorBody(body: unknown, fallback?: string): NormalizedError;
|
|
180
177
|
/**
|
|
181
178
|
* Reads a `Retry-After` header. RFC 9110 allows both delay-seconds and an
|
|
182
|
-
* HTTP-date;
|
|
179
|
+
* HTTP-date; the API sends seconds, but a proxy in front may not.
|
|
183
180
|
*
|
|
184
181
|
* @returns Milliseconds to wait, or `undefined` when the header is absent or junk.
|
|
185
182
|
*/
|