@wave-av/sdk 2.0.1 → 2.0.3
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/CHANGELOG.md +1 -1
- package/README.md +27 -23
- package/dist/audience.js +93 -0
- package/dist/audience.mjs +9 -0
- package/dist/camera-control.js +95 -0
- package/dist/camera-control.mjs +71 -0
- package/dist/captions-types.js +18 -0
- package/dist/captions-types.mjs +0 -0
- package/dist/captions.js +266 -0
- package/dist/captions.mjs +9 -0
- package/dist/chapters-types.js +18 -0
- package/dist/chapters-types.mjs +0 -0
- package/dist/chapters.js +280 -0
- package/dist/chapters.mjs +9 -0
- package/dist/chunk-362MRITF.mjs +46 -0
- package/dist/chunk-3ZLK4J3V.mjs +69 -0
- package/dist/chunk-4DG4OBRD.mjs +52 -0
- package/dist/chunk-4G7FMCMJ.mjs +68 -0
- package/dist/chunk-4KD5F6E3.mjs +0 -0
- package/dist/chunk-7M6XVUUK.mjs +241 -0
- package/dist/chunk-A344OOT7.mjs +243 -0
- package/dist/chunk-AI64YR5W.mjs +173 -0
- package/dist/chunk-C2GQ756E.mjs +57 -0
- package/dist/chunk-CO2VB72Z.mjs +255 -0
- package/dist/chunk-DWXWAILB.mjs +44 -0
- package/dist/chunk-FLEFYLDM.mjs +71 -0
- package/dist/chunk-H2YYTNUH.mjs +266 -0
- package/dist/chunk-IGDBED5P.mjs +246 -0
- package/dist/chunk-IL2SGWBC.mjs +0 -0
- package/dist/chunk-IVFZ5X4W.mjs +68 -0
- package/dist/chunk-JC32PG3T.mjs +114 -0
- package/dist/chunk-K5X42NLD.mjs +54 -0
- package/dist/chunk-KCEPNS2U.mjs +276 -0
- package/dist/chunk-LVOVF6XC.mjs +54 -0
- package/dist/chunk-M4Z33V3N.mjs +247 -0
- package/dist/chunk-M6FKIX75.mjs +0 -0
- package/dist/chunk-M744Z327.mjs +244 -0
- package/dist/chunk-MRFDPPFK.mjs +61 -0
- package/dist/chunk-MXU3Q23F.mjs +68 -0
- package/dist/chunk-NCVUZ746.mjs +60 -0
- package/dist/chunk-NLQVD2LF.mjs +210 -0
- package/dist/chunk-O6DOGYP5.mjs +238 -0
- package/dist/chunk-S25NY5GE.mjs +124 -0
- package/dist/chunk-TFHXBICQ.mjs +305 -0
- package/dist/chunk-TXWOA2VR.mjs +57 -0
- package/dist/chunk-UCDSNV22.mjs +63 -0
- package/dist/chunk-V5DWA5P4.mjs +279 -0
- package/dist/chunk-VLQQDYGP.mjs +173 -0
- package/dist/chunk-VPKZUXZW.mjs +53 -0
- package/dist/chunk-WS3PEFYJ.mjs +60 -0
- package/dist/chunk-XGAYMWRH.mjs +74 -0
- package/dist/chunk-XMM5J57W.mjs +0 -0
- package/dist/chunk-XWABBOSX.mjs +278 -0
- package/dist/chunk-Y6FXYEAI.mjs +10 -0
- package/dist/chunk-YBLXHI3M.mjs +257 -0
- package/dist/chunk-YEK26SSO.mjs +100 -0
- package/dist/chunk-YLCQKCZL.mjs +0 -0
- package/dist/chunk-YRKO4XI7.mjs +0 -0
- package/dist/chunk-ZJO7AP4Q.mjs +0 -0
- package/dist/client-types.js +18 -0
- package/dist/client-types.mjs +0 -0
- package/dist/client.js +311 -0
- package/dist/client.mjs +14 -0
- package/dist/clips-types.js +18 -0
- package/dist/clips-types.mjs +0 -0
- package/dist/clips.js +198 -0
- package/dist/clips.mjs +9 -0
- package/dist/cloud-switcher.js +80 -0
- package/dist/cloud-switcher.mjs +56 -0
- package/dist/collab-types.js +18 -0
- package/dist/collab-types.mjs +1 -0
- package/dist/collab.js +304 -0
- package/dist/collab.mjs +10 -0
- package/dist/connect.js +85 -0
- package/dist/connect.mjs +9 -0
- package/dist/creator.js +79 -0
- package/dist/creator.mjs +9 -0
- package/dist/desktop.js +77 -0
- package/dist/desktop.mjs +9 -0
- package/dist/distribution.js +88 -0
- package/dist/distribution.mjs +9 -0
- package/dist/drm.js +85 -0
- package/dist/drm.mjs +9 -0
- package/dist/edge.js +93 -0
- package/dist/edge.mjs +9 -0
- package/dist/editor-types.js +18 -0
- package/dist/editor-types.mjs +1 -0
- package/dist/editor.js +330 -0
- package/dist/editor.mjs +10 -0
- package/dist/fleet.js +149 -0
- package/dist/fleet.mjs +9 -0
- package/dist/ghost.js +139 -0
- package/dist/ghost.mjs +9 -0
- package/dist/index.js +0 -250
- package/dist/index.mjs +161 -5445
- package/dist/marketplace.js +82 -0
- package/dist/marketplace.mjs +9 -0
- package/dist/mesh.js +198 -0
- package/dist/mesh.mjs +9 -0
- package/dist/notifications.js +79 -0
- package/dist/notifications.mjs +9 -0
- package/dist/phone-types.js +18 -0
- package/dist/phone-types.mjs +0 -0
- package/dist/phone.js +269 -0
- package/dist/phone.mjs +9 -0
- package/dist/pipeline-types.js +18 -0
- package/dist/pipeline-types.mjs +0 -0
- package/dist/pipeline.js +263 -0
- package/dist/pipeline.mjs +9 -0
- package/dist/podcast.js +94 -0
- package/dist/podcast.mjs +9 -0
- package/dist/prism.js +82 -0
- package/dist/prism.mjs +9 -0
- package/dist/prompter.js +99 -0
- package/dist/prompter.mjs +76 -0
- package/dist/pulse.js +99 -0
- package/dist/pulse.mjs +9 -0
- package/dist/qr.js +71 -0
- package/dist/qr.mjs +9 -0
- package/dist/replay.js +62 -0
- package/dist/replay.mjs +38 -0
- package/dist/scene-types.js +18 -0
- package/dist/scene-types.mjs +1 -0
- package/dist/scene.js +271 -0
- package/dist/scene.mjs +10 -0
- package/dist/search-types.js +18 -0
- package/dist/search-types.mjs +1 -0
- package/dist/search.js +268 -0
- package/dist/search.mjs +10 -0
- package/dist/sentiment-types.js +18 -0
- package/dist/sentiment-types.mjs +0 -0
- package/dist/sentiment.js +235 -0
- package/dist/sentiment.mjs +9 -0
- package/dist/signage.js +93 -0
- package/dist/signage.mjs +9 -0
- package/dist/slides.js +78 -0
- package/dist/slides.mjs +9 -0
- package/dist/studio-ai-types.js +18 -0
- package/dist/studio-ai-types.mjs +1 -0
- package/dist/studio-ai.js +301 -0
- package/dist/studio-ai.mjs +10 -0
- package/dist/studio-types.js +18 -0
- package/dist/studio-types.mjs +1 -0
- package/dist/studio.js +303 -0
- package/dist/studio.mjs +10 -0
- package/dist/telemetry.js +124 -0
- package/dist/telemetry.mjs +15 -0
- package/dist/transcribe-types.js +18 -0
- package/dist/transcribe-types.mjs +1 -0
- package/dist/transcribe.js +282 -0
- package/dist/transcribe.mjs +10 -0
- package/dist/usb.js +69 -0
- package/dist/usb.mjs +9 -0
- package/dist/vault.js +96 -0
- package/dist/vault.mjs +9 -0
- package/dist/voice-types.js +18 -0
- package/dist/voice-types.mjs +0 -0
- package/dist/voice.js +272 -0
- package/dist/voice.mjs +9 -0
- package/dist/zoom.js +86 -0
- package/dist/zoom.mjs +9 -0
- package/package.json +5 -5
- package/dist/audience.d.ts +0 -104
- package/dist/audience.d.ts.map +0 -1
- package/dist/camera-control.d.ts +0 -54
- package/dist/camera-control.d.ts.map +0 -1
- package/dist/captions.d.ts +0 -362
- package/dist/captions.d.ts.map +0 -1
- package/dist/chapters.d.ts +0 -315
- package/dist/chapters.d.ts.map +0 -1
- package/dist/client.d.ts +0 -191
- package/dist/client.d.ts.map +0 -1
- package/dist/clips.d.ts +0 -258
- package/dist/clips.d.ts.map +0 -1
- package/dist/cloud-switcher.d.ts +0 -65
- package/dist/cloud-switcher.d.ts.map +0 -1
- package/dist/collab-types.d.ts +0 -204
- package/dist/collab-types.d.ts.map +0 -1
- package/dist/collab.d.ts +0 -226
- package/dist/collab.d.ts.map +0 -1
- package/dist/connect.d.ts +0 -88
- package/dist/connect.d.ts.map +0 -1
- package/dist/creator.d.ts +0 -109
- package/dist/creator.d.ts.map +0 -1
- package/dist/desktop.d.ts +0 -95
- package/dist/desktop.d.ts.map +0 -1
- package/dist/distribution.d.ts +0 -92
- package/dist/distribution.d.ts.map +0 -1
- package/dist/drm.d.ts +0 -87
- package/dist/drm.d.ts.map +0 -1
- package/dist/edge.d.ts +0 -112
- package/dist/edge.d.ts.map +0 -1
- package/dist/editor-types.d.ts +0 -236
- package/dist/editor-types.d.ts.map +0 -1
- package/dist/editor.d.ts +0 -206
- package/dist/editor.d.ts.map +0 -1
- package/dist/fleet.d.ts +0 -207
- package/dist/fleet.d.ts.map +0 -1
- package/dist/ghost.d.ts +0 -213
- package/dist/ghost.d.ts.map +0 -1
- package/dist/index.d.ts +0 -144
- package/dist/index.d.ts.map +0 -1
- package/dist/marketplace.d.ts +0 -90
- package/dist/marketplace.d.ts.map +0 -1
- package/dist/mesh.d.ts +0 -237
- package/dist/mesh.d.ts.map +0 -1
- package/dist/notifications.d.ts +0 -82
- package/dist/notifications.d.ts.map +0 -1
- package/dist/phone.d.ts +0 -369
- package/dist/phone.d.ts.map +0 -1
- package/dist/pipeline.d.ts +0 -409
- package/dist/pipeline.d.ts.map +0 -1
- package/dist/podcast.d.ts +0 -113
- package/dist/podcast.d.ts.map +0 -1
- package/dist/prism.d.ts +0 -132
- package/dist/prism.d.ts.map +0 -1
- package/dist/prompter.d.ts +0 -184
- package/dist/prompter.d.ts.map +0 -1
- package/dist/pulse.d.ts +0 -156
- package/dist/pulse.d.ts.map +0 -1
- package/dist/qr.d.ts +0 -82
- package/dist/qr.d.ts.map +0 -1
- package/dist/replay.d.ts +0 -52
- package/dist/replay.d.ts.map +0 -1
- package/dist/scene-types.d.ts +0 -190
- package/dist/scene-types.d.ts.map +0 -1
- package/dist/scene.d.ts +0 -213
- package/dist/scene.d.ts.map +0 -1
- package/dist/search-types.d.ts +0 -210
- package/dist/search-types.d.ts.map +0 -1
- package/dist/search.d.ts +0 -250
- package/dist/search.d.ts.map +0 -1
- package/dist/sentiment.d.ts +0 -378
- package/dist/sentiment.d.ts.map +0 -1
- package/dist/signage.d.ts +0 -101
- package/dist/signage.d.ts.map +0 -1
- package/dist/slides.d.ts +0 -68
- package/dist/slides.d.ts.map +0 -1
- package/dist/studio-ai-types.d.ts +0 -198
- package/dist/studio-ai-types.d.ts.map +0 -1
- package/dist/studio-ai.d.ts +0 -218
- package/dist/studio-ai.d.ts.map +0 -1
- package/dist/studio-types.d.ts +0 -267
- package/dist/studio-types.d.ts.map +0 -1
- package/dist/studio.d.ts +0 -234
- package/dist/studio.d.ts.map +0 -1
- package/dist/telemetry.d.ts +0 -76
- package/dist/telemetry.d.ts.map +0 -1
- package/dist/transcribe-types.d.ts +0 -153
- package/dist/transcribe-types.d.ts.map +0 -1
- package/dist/transcribe.d.ts +0 -218
- package/dist/transcribe.d.ts.map +0 -1
- package/dist/usb.d.ts +0 -64
- package/dist/usb.d.ts.map +0 -1
- package/dist/vault.d.ts +0 -121
- package/dist/vault.d.ts.map +0 -1
- package/dist/voice.d.ts +0 -307
- package/dist/voice.d.ts.map +0 -1
- package/dist/zoom.d.ts +0 -91
- package/dist/zoom.d.ts.map +0 -1
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import {
|
|
2
|
+
initTelemetry
|
|
3
|
+
} from "./chunk-YEK26SSO.mjs";
|
|
4
|
+
|
|
5
|
+
// src/client.ts
|
|
6
|
+
import { EventEmitter } from "eventemitter3";
|
|
7
|
+
var WaveError = class extends Error {
|
|
8
|
+
code;
|
|
9
|
+
statusCode;
|
|
10
|
+
requestId;
|
|
11
|
+
details;
|
|
12
|
+
retryable;
|
|
13
|
+
constructor(message, code, statusCode, requestId, details) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "WaveError";
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.statusCode = statusCode;
|
|
18
|
+
this.requestId = requestId;
|
|
19
|
+
this.details = details;
|
|
20
|
+
this.retryable = this.isRetryable(statusCode, code);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var RateLimitError = class extends WaveError {
|
|
24
|
+
retryAfter;
|
|
25
|
+
constructor(message, retryAfter, requestId) {
|
|
26
|
+
super(message, "RATE_LIMITED", 429, requestId);
|
|
27
|
+
this.name = "RateLimitError";
|
|
28
|
+
this.retryAfter = retryAfter;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var WaveClient = class extends EventEmitter {
|
|
32
|
+
config;
|
|
33
|
+
constructor(config) {
|
|
34
|
+
super();
|
|
35
|
+
if (!config.apiKey) {
|
|
36
|
+
throw new Error("WAVE SDK: apiKey is required");
|
|
37
|
+
}
|
|
38
|
+
this.config = {
|
|
39
|
+
apiKey: config.apiKey,
|
|
40
|
+
organizationId: config.organizationId || "",
|
|
41
|
+
baseUrl: config.baseUrl || "https://api.wave.online",
|
|
42
|
+
timeout: config.timeout || 3e4,
|
|
43
|
+
maxRetries: config.maxRetries ?? 3,
|
|
44
|
+
debug: config.debug || false,
|
|
45
|
+
customHeaders: config.customHeaders || {},
|
|
46
|
+
telemetry: config.telemetry
|
|
47
|
+
};
|
|
48
|
+
if (config.telemetry) {
|
|
49
|
+
initTelemetry(config.telemetry);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Make a GET request
|
|
54
|
+
*/
|
|
55
|
+
async get(path, options) {
|
|
56
|
+
return this.request(path, { ...options, method: "GET" });
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Make a POST request
|
|
60
|
+
*/
|
|
61
|
+
async post(path, body, options) {
|
|
62
|
+
return this.request(path, {
|
|
63
|
+
...options,
|
|
64
|
+
method: "POST",
|
|
65
|
+
body: body ? JSON.stringify(body) : void 0
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Make a PUT request
|
|
70
|
+
*/
|
|
71
|
+
async put(path, body, options) {
|
|
72
|
+
return this.request(path, {
|
|
73
|
+
...options,
|
|
74
|
+
method: "PUT",
|
|
75
|
+
body: body ? JSON.stringify(body) : void 0
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Make a PATCH request
|
|
80
|
+
*/
|
|
81
|
+
async patch(path, body, options) {
|
|
82
|
+
return this.request(path, {
|
|
83
|
+
...options,
|
|
84
|
+
method: "PATCH",
|
|
85
|
+
body: body ? JSON.stringify(body) : void 0
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Make a DELETE request
|
|
90
|
+
*/
|
|
91
|
+
async delete(path, options) {
|
|
92
|
+
return this.request(path, { ...options, method: "DELETE" });
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Make an API request with retry logic
|
|
96
|
+
*/
|
|
97
|
+
async request(path, options = {}) {
|
|
98
|
+
const { params, noRetry, timeout: requestTimeout, ...fetchOptions } = options;
|
|
99
|
+
let url = `${this.config.baseUrl}${path}`;
|
|
100
|
+
if (params) {
|
|
101
|
+
const searchParams = new URLSearchParams();
|
|
102
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
103
|
+
if (value !== void 0) {
|
|
104
|
+
searchParams.set(key, String(value));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
const queryString = searchParams.toString();
|
|
108
|
+
if (queryString) {
|
|
109
|
+
url += `?${queryString}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return this.executeWithRetry(
|
|
113
|
+
url,
|
|
114
|
+
{
|
|
115
|
+
...fetchOptions,
|
|
116
|
+
headers: this.buildHeaders(fetchOptions.headers)
|
|
117
|
+
},
|
|
118
|
+
noRetry ? 0 : this.config.maxRetries,
|
|
119
|
+
requestTimeout || this.config.timeout
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Execute request with exponential backoff retry
|
|
124
|
+
*/
|
|
125
|
+
async executeWithRetry(url, options, maxRetries, timeout) {
|
|
126
|
+
const method = options.method || "GET";
|
|
127
|
+
let lastError = null;
|
|
128
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
129
|
+
try {
|
|
130
|
+
this.emit("request.start", url, method);
|
|
131
|
+
const startTime = Date.now();
|
|
132
|
+
const response = await this.fetchWithTimeout(url, options, timeout);
|
|
133
|
+
const duration = Date.now() - startTime;
|
|
134
|
+
if (response.status === 429) {
|
|
135
|
+
const retryAfter = this.parseRetryAfter(response);
|
|
136
|
+
this.emit("rate_limit.hit", retryAfter);
|
|
137
|
+
if (attempt < maxRetries) {
|
|
138
|
+
this.emit("request.retry", url, method, attempt + 1, retryAfter);
|
|
139
|
+
await this.sleep(retryAfter);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
throw new RateLimitError(
|
|
143
|
+
"Rate limit exceeded",
|
|
144
|
+
retryAfter,
|
|
145
|
+
response.headers.get("x-request-id") || void 0
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
if (!response.ok) {
|
|
149
|
+
const error = await this.parseErrorResponse(response);
|
|
150
|
+
if (error.retryable && attempt < maxRetries) {
|
|
151
|
+
const delay = this.calculateBackoff(attempt);
|
|
152
|
+
this.emit("request.retry", url, method, attempt + 1, delay);
|
|
153
|
+
await this.sleep(delay);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
this.emit("request.success", url, method, duration);
|
|
159
|
+
const contentType = response.headers.get("content-type");
|
|
160
|
+
if (contentType?.includes("application/json")) {
|
|
161
|
+
return response.json();
|
|
162
|
+
}
|
|
163
|
+
return {};
|
|
164
|
+
} catch (error) {
|
|
165
|
+
lastError = error;
|
|
166
|
+
if (error instanceof WaveError && !error.retryable) {
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
if (error instanceof TypeError || error instanceof Error && error.name === "AbortError") {
|
|
170
|
+
if (attempt < maxRetries) {
|
|
171
|
+
const delay = this.calculateBackoff(attempt);
|
|
172
|
+
this.emit("request.retry", url, method, attempt + 1, delay);
|
|
173
|
+
await this.sleep(delay);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
this.emit("request.error", url, method, error);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
throw lastError || new WaveError("Request failed after retries", "UNKNOWN_ERROR", 0);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Fetch with timeout
|
|
184
|
+
*/
|
|
185
|
+
async fetchWithTimeout(url, options, timeout) {
|
|
186
|
+
const controller = new AbortController();
|
|
187
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
188
|
+
try {
|
|
189
|
+
const response = await fetch(url, {
|
|
190
|
+
...options,
|
|
191
|
+
signal: controller.signal
|
|
192
|
+
});
|
|
193
|
+
return response;
|
|
194
|
+
} finally {
|
|
195
|
+
clearTimeout(timeoutId);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Build request headers
|
|
200
|
+
*/
|
|
201
|
+
buildHeaders(additionalHeaders) {
|
|
202
|
+
const headers = {
|
|
203
|
+
"Authorization": `Bearer ${this.config.apiKey}`,
|
|
204
|
+
"Content-Type": "application/json",
|
|
205
|
+
"Accept": "application/json",
|
|
206
|
+
"User-Agent": `wave-sdk-typescript/1.0.0`,
|
|
207
|
+
...this.config.customHeaders
|
|
208
|
+
};
|
|
209
|
+
if (this.config.organizationId) {
|
|
210
|
+
headers["X-Organization-Id"] = this.config.organizationId;
|
|
211
|
+
}
|
|
212
|
+
if (additionalHeaders) {
|
|
213
|
+
if (additionalHeaders instanceof Headers) {
|
|
214
|
+
additionalHeaders.forEach((value, key) => {
|
|
215
|
+
headers[key] = value;
|
|
216
|
+
});
|
|
217
|
+
} else if (Array.isArray(additionalHeaders)) {
|
|
218
|
+
additionalHeaders.forEach(([key, value]) => {
|
|
219
|
+
headers[key] = value;
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
Object.assign(headers, additionalHeaders);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return headers;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Parse error response
|
|
229
|
+
*/
|
|
230
|
+
/**
|
|
231
|
+
* Parse Retry-After header
|
|
232
|
+
*/
|
|
233
|
+
/**
|
|
234
|
+
* Calculate exponential backoff delay
|
|
235
|
+
*/
|
|
236
|
+
calculateBackoff(attempt) {
|
|
237
|
+
const baseDelay = 1e3;
|
|
238
|
+
const maxDelay = 3e4;
|
|
239
|
+
const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
|
|
240
|
+
return delay + Math.random() * delay * 0.25;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Sleep utility
|
|
244
|
+
*/
|
|
245
|
+
sleep(ms) {
|
|
246
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Log debug message
|
|
250
|
+
*/
|
|
251
|
+
log(message, ...args) {
|
|
252
|
+
if (this.config.debug) {
|
|
253
|
+
console.log(`[WaveSDK] ${message}`, ...args);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
function createClient(config) {
|
|
258
|
+
return new WaveClient(config);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export {
|
|
262
|
+
WaveError,
|
|
263
|
+
RateLimitError,
|
|
264
|
+
WaveClient,
|
|
265
|
+
createClient
|
|
266
|
+
};
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// src/scene.ts
|
|
2
|
+
var SceneAPI = class {
|
|
3
|
+
client;
|
|
4
|
+
basePath = "/v1/scene";
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Start scene detection
|
|
10
|
+
*
|
|
11
|
+
* Requires: scene:detect permission
|
|
12
|
+
*/
|
|
13
|
+
async detect(request) {
|
|
14
|
+
return this.client.post(`${this.basePath}/detect`, request);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get scene detection job
|
|
18
|
+
*
|
|
19
|
+
* Requires: scene:read permission
|
|
20
|
+
*/
|
|
21
|
+
async getDetection(detectionId) {
|
|
22
|
+
return this.client.get(`${this.basePath}/${detectionId}`);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Remove scene detection
|
|
26
|
+
*
|
|
27
|
+
* Requires: scene:remove permission (server-side RBAC enforced)
|
|
28
|
+
*/
|
|
29
|
+
async removeDetection(detectionId) {
|
|
30
|
+
await this.client.delete(
|
|
31
|
+
`${this.basePath}/${detectionId}`,
|
|
32
|
+
{ method: "DELETE" }
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* List scene detections
|
|
37
|
+
*
|
|
38
|
+
* Requires: scene:read permission
|
|
39
|
+
*/
|
|
40
|
+
async listDetections(params) {
|
|
41
|
+
return this.client.get(this.basePath, {
|
|
42
|
+
params
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get scenes for a detection
|
|
47
|
+
*
|
|
48
|
+
* Requires: scene:read permission
|
|
49
|
+
*/
|
|
50
|
+
async getScenes(detectionId, params) {
|
|
51
|
+
return this.client.get(
|
|
52
|
+
`${this.basePath}/${detectionId}/scenes`,
|
|
53
|
+
{ params }
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get a specific scene
|
|
58
|
+
*
|
|
59
|
+
* Requires: scene:read permission
|
|
60
|
+
*/
|
|
61
|
+
async getScene(detectionId, sceneId) {
|
|
62
|
+
return this.client.get(
|
|
63
|
+
`${this.basePath}/${detectionId}/scenes/${sceneId}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Update scene metadata
|
|
68
|
+
*
|
|
69
|
+
* Requires: scene:update permission
|
|
70
|
+
*/
|
|
71
|
+
async updateScene(detectionId, sceneId, updates) {
|
|
72
|
+
return this.client.patch(
|
|
73
|
+
`${this.basePath}/${detectionId}/scenes/${sceneId}`,
|
|
74
|
+
updates
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get scene at a specific timestamp
|
|
79
|
+
*
|
|
80
|
+
* Requires: scene:read permission
|
|
81
|
+
*/
|
|
82
|
+
async getSceneAtTime(detectionId, timestamp) {
|
|
83
|
+
try {
|
|
84
|
+
return await this.client.get(
|
|
85
|
+
`${this.basePath}/${detectionId}/scenes/at`,
|
|
86
|
+
{ params: { timestamp } }
|
|
87
|
+
);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error.statusCode === 404) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get scene boundaries (transitions)
|
|
97
|
+
*
|
|
98
|
+
* Requires: scene:read permission
|
|
99
|
+
*/
|
|
100
|
+
async getBoundaries(detectionId, params) {
|
|
101
|
+
return this.client.get(
|
|
102
|
+
`${this.basePath}/${detectionId}/boundaries`,
|
|
103
|
+
{ params }
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Detect scene boundaries only (without full analysis)
|
|
108
|
+
*
|
|
109
|
+
* Requires: scene:detect permission
|
|
110
|
+
*/
|
|
111
|
+
async detectBoundaries(mediaId, mediaType, options) {
|
|
112
|
+
return this.client.post(`${this.basePath}/boundaries`, {
|
|
113
|
+
media_id: mediaId,
|
|
114
|
+
media_type: mediaType,
|
|
115
|
+
...options
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get shots for a scene
|
|
120
|
+
*
|
|
121
|
+
* Requires: scene:read permission
|
|
122
|
+
*/
|
|
123
|
+
async getShots(detectionId, sceneId, params) {
|
|
124
|
+
return this.client.get(
|
|
125
|
+
`${this.basePath}/${detectionId}/scenes/${sceneId}/shots`,
|
|
126
|
+
{ params }
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get all shots for a detection
|
|
131
|
+
*
|
|
132
|
+
* Requires: scene:read permission
|
|
133
|
+
*/
|
|
134
|
+
async getAllShots(detectionId, params) {
|
|
135
|
+
return this.client.get(`${this.basePath}/${detectionId}/shots`, { params });
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get scene summary/statistics
|
|
139
|
+
*
|
|
140
|
+
* Requires: scene:read permission
|
|
141
|
+
*/
|
|
142
|
+
async getSummary(detectionId) {
|
|
143
|
+
return this.client.get(`${this.basePath}/${detectionId}/summary`);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get visual timeline
|
|
147
|
+
*
|
|
148
|
+
* Requires: scene:read permission
|
|
149
|
+
*/
|
|
150
|
+
async getTimeline(detectionId, options) {
|
|
151
|
+
return this.client.get(`${this.basePath}/${detectionId}/timeline`, {
|
|
152
|
+
params: options
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Compare scenes between detections
|
|
157
|
+
*
|
|
158
|
+
* Requires: scene:read permission
|
|
159
|
+
*/
|
|
160
|
+
async compareScenes(sourceDetectionId, targetDetectionId, options) {
|
|
161
|
+
return this.client.post(`${this.basePath}/compare`, {
|
|
162
|
+
source_detection_id: sourceDetectionId,
|
|
163
|
+
target_detection_id: targetDetectionId,
|
|
164
|
+
...options
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Find similar scenes across all content
|
|
169
|
+
*
|
|
170
|
+
* Requires: scene:read permission
|
|
171
|
+
*/
|
|
172
|
+
async findSimilarScenes(detectionId, sceneId, options) {
|
|
173
|
+
return this.client.get(`${this.basePath}/${detectionId}/scenes/${sceneId}/similar`, {
|
|
174
|
+
params: options
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Export scene data
|
|
179
|
+
*
|
|
180
|
+
* Requires: scene:read permission
|
|
181
|
+
*/
|
|
182
|
+
async exportDetection(detectionId, format) {
|
|
183
|
+
return this.client.post(`${this.basePath}/${detectionId}/export`, { format });
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Generate scene thumbnails
|
|
187
|
+
*
|
|
188
|
+
* Requires: scene:update permission
|
|
189
|
+
*/
|
|
190
|
+
async generateThumbnails(detectionId, options) {
|
|
191
|
+
return this.client.post(`${this.basePath}/${detectionId}/thumbnails`, options);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Wait for scene detection to complete
|
|
195
|
+
*/
|
|
196
|
+
async waitForReady(detectionId, options) {
|
|
197
|
+
const pollInterval = options?.pollInterval || 3e3;
|
|
198
|
+
const timeout = options?.timeout || 18e5;
|
|
199
|
+
const startTime = Date.now();
|
|
200
|
+
while (Date.now() - startTime < timeout) {
|
|
201
|
+
const detection = await this.getDetection(detectionId);
|
|
202
|
+
if (options?.onProgress) {
|
|
203
|
+
options.onProgress(detection);
|
|
204
|
+
}
|
|
205
|
+
if (detection.status === "ready") {
|
|
206
|
+
return detection;
|
|
207
|
+
}
|
|
208
|
+
if (detection.status === "failed") {
|
|
209
|
+
throw new Error(
|
|
210
|
+
`Scene detection failed: ${detection.error || "Unknown error"}`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
214
|
+
}
|
|
215
|
+
throw new Error(`Scene detection timed out after ${timeout}ms`);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Merge scenes
|
|
219
|
+
*
|
|
220
|
+
* Requires: scene:update permission
|
|
221
|
+
*/
|
|
222
|
+
async mergeScenes(detectionId, sceneIds, options) {
|
|
223
|
+
return this.client.post(
|
|
224
|
+
`${this.basePath}/${detectionId}/scenes/merge`,
|
|
225
|
+
{ scene_ids: sceneIds, ...options }
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Split scene at timestamp
|
|
230
|
+
*
|
|
231
|
+
* Requires: scene:update permission
|
|
232
|
+
*/
|
|
233
|
+
async splitScene(detectionId, sceneId, splitTime) {
|
|
234
|
+
return this.client.post(`${this.basePath}/${detectionId}/scenes/${sceneId}/split`, {
|
|
235
|
+
split_time: splitTime
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
function createSceneAPI(client) {
|
|
240
|
+
return new SceneAPI(client);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export {
|
|
244
|
+
SceneAPI,
|
|
245
|
+
createSceneAPI
|
|
246
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// src/signage.ts
|
|
2
|
+
var SignageAPI = class {
|
|
3
|
+
client;
|
|
4
|
+
basePath = "/v1/signage";
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
async listDisplays(params) {
|
|
9
|
+
return this.client.get(`${this.basePath}/displays`, {
|
|
10
|
+
params
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async getDisplay(displayId) {
|
|
14
|
+
return this.client.get(`${this.basePath}/displays/${displayId}`);
|
|
15
|
+
}
|
|
16
|
+
async registerDisplay(request) {
|
|
17
|
+
return this.client.post(`${this.basePath}/displays`, request);
|
|
18
|
+
}
|
|
19
|
+
async updateDisplay(displayId, updates) {
|
|
20
|
+
return this.client.patch(`${this.basePath}/displays/${displayId}`, updates);
|
|
21
|
+
}
|
|
22
|
+
async removeDisplay(displayId) {
|
|
23
|
+
await this.client.delete(`${this.basePath}/displays/${displayId}`);
|
|
24
|
+
}
|
|
25
|
+
async createPlaylist(request) {
|
|
26
|
+
return this.client.post(`${this.basePath}/playlists`, request);
|
|
27
|
+
}
|
|
28
|
+
async updatePlaylist(playlistId, updates) {
|
|
29
|
+
return this.client.patch(`${this.basePath}/playlists/${playlistId}`, updates);
|
|
30
|
+
}
|
|
31
|
+
async removePlaylist(playlistId) {
|
|
32
|
+
await this.client.delete(`${this.basePath}/playlists/${playlistId}`);
|
|
33
|
+
}
|
|
34
|
+
async listPlaylists(params) {
|
|
35
|
+
return this.client.get(`${this.basePath}/playlists`, {
|
|
36
|
+
params
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async assignPlaylist(displayId, playlistId) {
|
|
40
|
+
await this.client.post(`${this.basePath}/displays/${displayId}/playlist`, {
|
|
41
|
+
playlist_id: playlistId
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async scheduleContent(request) {
|
|
45
|
+
return this.client.post(`${this.basePath}/schedules`, request);
|
|
46
|
+
}
|
|
47
|
+
async listSchedules(displayId) {
|
|
48
|
+
const path = displayId ? `${this.basePath}/displays/${displayId}/schedules` : `${this.basePath}/schedules`;
|
|
49
|
+
return this.client.get(path);
|
|
50
|
+
}
|
|
51
|
+
async removeSchedule(scheduleId) {
|
|
52
|
+
await this.client.delete(`${this.basePath}/schedules/${scheduleId}`);
|
|
53
|
+
}
|
|
54
|
+
async configureDisplay(displayId, config) {
|
|
55
|
+
return this.client.patch(
|
|
56
|
+
`${this.basePath}/displays/${displayId}/config`,
|
|
57
|
+
config
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function createSignageAPI(client) {
|
|
62
|
+
return new SignageAPI(client);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export {
|
|
66
|
+
SignageAPI,
|
|
67
|
+
createSignageAPI
|
|
68
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// src/ghost.ts
|
|
2
|
+
var GhostAPI = class {
|
|
3
|
+
client;
|
|
4
|
+
basePath = "/v1/productions";
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Start an Autopilot directing session
|
|
10
|
+
*
|
|
11
|
+
* Requires: ghost:create permission
|
|
12
|
+
*/
|
|
13
|
+
async start(request) {
|
|
14
|
+
return this.client.post(
|
|
15
|
+
`${this.basePath}/${request.production_id}/ghost`,
|
|
16
|
+
request
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get the current Autopilot session for a production
|
|
21
|
+
*
|
|
22
|
+
* Requires: ghost:read permission
|
|
23
|
+
*/
|
|
24
|
+
async get(productionId) {
|
|
25
|
+
return this.client.get(`${this.basePath}/${productionId}/ghost`);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Update an Autopilot session
|
|
29
|
+
*
|
|
30
|
+
* Requires: ghost:update permission
|
|
31
|
+
*/
|
|
32
|
+
async update(productionId, request) {
|
|
33
|
+
return this.client.patch(`${this.basePath}/${productionId}/ghost`, request);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Stop an Autopilot session
|
|
37
|
+
*
|
|
38
|
+
* Requires: ghost:stop permission
|
|
39
|
+
*/
|
|
40
|
+
async stop(productionId) {
|
|
41
|
+
return this.client.post(`${this.basePath}/${productionId}/ghost/stop`);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Pause an Autopilot session
|
|
45
|
+
*
|
|
46
|
+
* Requires: ghost:update permission
|
|
47
|
+
*/
|
|
48
|
+
async pause(productionId) {
|
|
49
|
+
return this.client.post(`${this.basePath}/${productionId}/ghost/pause`);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resume a paused Autopilot session
|
|
53
|
+
*
|
|
54
|
+
* Requires: ghost:update permission
|
|
55
|
+
*/
|
|
56
|
+
async resume(productionId) {
|
|
57
|
+
return this.client.post(`${this.basePath}/${productionId}/ghost/resume`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Override the current shot with a manual selection
|
|
61
|
+
*
|
|
62
|
+
* Requires: ghost:override permission
|
|
63
|
+
*/
|
|
64
|
+
async override(productionId, override) {
|
|
65
|
+
await this.client.post(`${this.basePath}/${productionId}/ghost/override`, override);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* List AI suggestions for a production's Autopilot session
|
|
69
|
+
*
|
|
70
|
+
* Requires: ghost:read permission
|
|
71
|
+
*/
|
|
72
|
+
async listSuggestions(productionId, params) {
|
|
73
|
+
return this.client.get(
|
|
74
|
+
`${this.basePath}/${productionId}/ghost/suggestions`,
|
|
75
|
+
{ params }
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Accept an AI suggestion
|
|
80
|
+
*
|
|
81
|
+
* Requires: ghost:update permission
|
|
82
|
+
*/
|
|
83
|
+
async acceptSuggestion(productionId, suggestionId) {
|
|
84
|
+
return this.client.post(
|
|
85
|
+
`${this.basePath}/${productionId}/ghost/suggestions/${suggestionId}/accept`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Reject an AI suggestion
|
|
90
|
+
*
|
|
91
|
+
* Requires: ghost:update permission
|
|
92
|
+
*/
|
|
93
|
+
async rejectSuggestion(productionId, suggestionId) {
|
|
94
|
+
return this.client.post(
|
|
95
|
+
`${this.basePath}/${productionId}/ghost/suggestions/${suggestionId}/reject`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get directing statistics for a production's Autopilot session
|
|
100
|
+
*
|
|
101
|
+
* Requires: ghost:read permission
|
|
102
|
+
*/
|
|
103
|
+
async getStats(productionId) {
|
|
104
|
+
return this.client.get(`${this.basePath}/${productionId}/ghost/stats`);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
function createGhostAPI(client) {
|
|
108
|
+
return new GhostAPI(client);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export {
|
|
112
|
+
GhostAPI,
|
|
113
|
+
createGhostAPI
|
|
114
|
+
};
|